For nonbonded interactions with group cutoff scheme.
Change-Id: I2037f94c24126f103fa232e77783775a62821f54
file(GLOB NONBONDED_AVX_256_SINGLE_SOURCES nb_kernel_avx_256_single/*.c)
endif()
+if(GMX_CPU_ACCELERATION STREQUAL "SSE2" AND GMX_DOUBLE)
+ file(GLOB NONBONDED_SSE2_DOUBLE_SOURCES nb_kernel_sse2_double/*.c)
+endif()
+
# These sources will be used in the parent directory's CMakeLists.txt
-set(NONBONDED_SOURCES ${NONBONDED_SOURCES} ${NONBONDED_SSE2_SINGLE_SOURCES} ${NONBONDED_SSE4_1_SINGLE_SOURCES} ${NONBONDED_AVX_128_FMA_SINGLE_SOURCES} ${NONBONDED_AVX_256_SINGLE_SOURCES} PARENT_SCOPE)
+set(NONBONDED_SOURCES ${NONBONDED_SOURCES} ${NONBONDED_SSE2_SINGLE_SOURCES} ${NONBONDED_SSE4_1_SINGLE_SOURCES} ${NONBONDED_AVX_128_FMA_SINGLE_SOURCES} ${NONBONDED_AVX_256_SINGLE_SOURCES} ${NONBONDED_SSE2_DOUBLE_SOURCES} PARENT_SCOPE)
--- /dev/null
+/*
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2011-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU Lesser General Public License.
+ *
+ * In plain-speak: do not worry about classes/macros/templates either - only
+ * changes to the library have to be LGPL, not an application linking with it.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website!
+ */
+#ifndef _kernelutil_x86_sse2_double_h_
+#define _kernelutil_x86_sse2_double_h_
+
+#include <math.h>
+
+#include "gmx_x86_sse2.h"
+
+#include <stdio.h>
+
+
+/* Normal sum of four ymm registers */
+#define gmx_mm_sum4_pd(t0,t1,t2,t3) _mm_add_pd(_mm_add_pd(t0,t1),_mm_add_pd(t2,t3))
+
+static int
+gmx_mm_any_lt(__m128d a, __m128d b)
+{
+ return _mm_movemask_pd(_mm_cmplt_pd(a,b));
+}
+
+static gmx_inline __m128d
+gmx_mm_calc_rsq_pd(__m128d dx, __m128d dy, __m128d dz)
+{
+ return _mm_add_pd( _mm_add_pd( _mm_mul_pd(dx,dx), _mm_mul_pd(dy,dy) ), _mm_mul_pd(dz,dz) );
+}
+
+
+/* Load a double value from 1-2 places, merge into xmm register */
+static gmx_inline __m128d
+gmx_mm_load_2real_swizzle_pd(const double * gmx_restrict ptrA,
+ const double * gmx_restrict ptrB)
+{
+ return _mm_unpacklo_pd(_mm_load_sd(ptrA),_mm_load_sd(ptrB));
+}
+
+static gmx_inline __m128d
+gmx_mm_load_1real_pd(const double * gmx_restrict ptrA)
+{
+ return _mm_load_sd(ptrA);
+}
+
+
+static gmx_inline void
+gmx_mm_store_2real_swizzle_pd(double * gmx_restrict ptrA,
+ double * gmx_restrict ptrB,
+ __m128d xmm1)
+{
+ __m128d t2;
+
+ t2 = _mm_unpackhi_pd(xmm1,xmm1);
+ _mm_store_sd(ptrA,xmm1);
+ _mm_store_sd(ptrB,t2);
+}
+
+static gmx_inline void
+gmx_mm_store_1real_pd(double * gmx_restrict ptrA, __m128d xmm1)
+{
+ _mm_store_sd(ptrA,xmm1);
+}
+
+
+/* Similar to store, but increments value in memory */
+static gmx_inline void
+gmx_mm_increment_2real_swizzle_pd(double * gmx_restrict ptrA,
+ double * gmx_restrict ptrB, __m128d xmm1)
+{
+ __m128d t1;
+
+ t1 = _mm_unpackhi_pd(xmm1,xmm1);
+ xmm1 = _mm_add_sd(xmm1,_mm_load_sd(ptrA));
+ t1 = _mm_add_sd(t1,_mm_load_sd(ptrB));
+ _mm_store_sd(ptrA,xmm1);
+ _mm_store_sd(ptrB,t1);
+}
+
+static gmx_inline void
+gmx_mm_increment_1real_pd(double * gmx_restrict ptrA, __m128d xmm1)
+{
+ __m128d tmp;
+
+ tmp = gmx_mm_load_1real_pd(ptrA);
+ tmp = _mm_add_sd(tmp,xmm1);
+ gmx_mm_store_1real_pd(ptrA,tmp);
+}
+
+
+static gmx_inline void
+gmx_mm_load_2pair_swizzle_pd(const double * gmx_restrict p1,
+ const double * gmx_restrict p2,
+ __m128d * gmx_restrict c6,
+ __m128d * gmx_restrict c12)
+{
+ __m128d t1,t2,t3;
+
+ t1 = _mm_loadu_pd(p1);
+ t2 = _mm_loadu_pd(p2);
+ *c6 = _mm_unpacklo_pd(t1,t2);
+ *c12 = _mm_unpackhi_pd(t1,t2);
+}
+
+static gmx_inline void
+gmx_mm_load_1pair_swizzle_pd(const double * gmx_restrict p1,
+ __m128d * gmx_restrict c6,
+ __m128d * gmx_restrict c12)
+{
+ *c6 = _mm_load_sd(p1);
+ *c12 = _mm_load_sd(p1+1);
+}
+
+
+
+static gmx_inline void
+gmx_mm_load_shift_and_1rvec_broadcast_pd(const double * gmx_restrict xyz_shift,
+ const double * gmx_restrict xyz,
+ __m128d * gmx_restrict x1,
+ __m128d * gmx_restrict y1,
+ __m128d * gmx_restrict z1)
+{
+ __m128d mem_xy,mem_z,mem_sxy,mem_sz;
+
+ mem_xy = _mm_loadu_pd(xyz);
+ mem_z = _mm_load_sd(xyz+2);
+ mem_sxy = _mm_loadu_pd(xyz_shift);
+ mem_sz = _mm_load_sd(xyz_shift+2);
+
+ mem_xy = _mm_add_pd(mem_xy,mem_sxy);
+ mem_z = _mm_add_pd(mem_z,mem_sz);
+
+ *x1 = _mm_shuffle_pd(mem_xy,mem_xy,_MM_SHUFFLE2(0,0));
+ *y1 = _mm_shuffle_pd(mem_xy,mem_xy,_MM_SHUFFLE2(1,1));
+ *z1 = _mm_shuffle_pd(mem_z,mem_z,_MM_SHUFFLE2(0,0));
+}
+
+
+static gmx_inline void
+gmx_mm_load_shift_and_3rvec_broadcast_pd(const double * gmx_restrict xyz_shift,
+ const double * gmx_restrict xyz,
+ __m128d * gmx_restrict x1, __m128d * gmx_restrict y1, __m128d * gmx_restrict z1,
+ __m128d * gmx_restrict x2, __m128d * gmx_restrict y2, __m128d * gmx_restrict z2,
+ __m128d * gmx_restrict x3, __m128d * gmx_restrict y3, __m128d * gmx_restrict z3)
+{
+ __m128d t1,t2,t3,t4,t5,sxy,sz,szx,syz;
+
+ t1 = _mm_loadu_pd(xyz);
+ t2 = _mm_loadu_pd(xyz+2);
+ t3 = _mm_loadu_pd(xyz+4);
+ t4 = _mm_loadu_pd(xyz+6);
+ t5 = _mm_load_sd(xyz+8);
+
+ sxy = _mm_loadu_pd(xyz_shift);
+ sz = _mm_load_sd(xyz_shift+2);
+ szx = _mm_shuffle_pd(sz,sxy,_MM_SHUFFLE2(0,0));
+ syz = _mm_shuffle_pd(sxy,sz,_MM_SHUFFLE2(0,1));
+
+ t1 = _mm_add_pd(t1,sxy);
+ t2 = _mm_add_pd(t2,szx);
+ t3 = _mm_add_pd(t3,syz);
+ t4 = _mm_add_pd(t4,sxy);
+ t5 = _mm_add_sd(t5,sz);
+
+ *x1 = _mm_shuffle_pd(t1,t1,_MM_SHUFFLE2(0,0));
+ *y1 = _mm_shuffle_pd(t1,t1,_MM_SHUFFLE2(1,1));
+ *z1 = _mm_shuffle_pd(t2,t2,_MM_SHUFFLE2(0,0));
+ *x2 = _mm_shuffle_pd(t2,t2,_MM_SHUFFLE2(1,1));
+ *y2 = _mm_shuffle_pd(t3,t3,_MM_SHUFFLE2(0,0));
+ *z2 = _mm_shuffle_pd(t3,t3,_MM_SHUFFLE2(1,1));
+ *x3 = _mm_shuffle_pd(t4,t4,_MM_SHUFFLE2(0,0));
+ *y3 = _mm_shuffle_pd(t4,t4,_MM_SHUFFLE2(1,1));
+ *z3 = _mm_shuffle_pd(t5,t5,_MM_SHUFFLE2(0,0));
+}
+
+
+static gmx_inline void
+gmx_mm_load_shift_and_4rvec_broadcast_pd(const double * gmx_restrict xyz_shift,
+ const double * gmx_restrict xyz,
+ __m128d * gmx_restrict x1, __m128d * gmx_restrict y1, __m128d * gmx_restrict z1,
+ __m128d * gmx_restrict x2, __m128d * gmx_restrict y2, __m128d * gmx_restrict z2,
+ __m128d * gmx_restrict x3, __m128d * gmx_restrict y3, __m128d * gmx_restrict z3,
+ __m128d * gmx_restrict x4, __m128d * gmx_restrict y4, __m128d * gmx_restrict z4)
+{
+ __m128d t1,t2,t3,t4,t5,t6,sxy,sz,szx,syz;
+
+ t1 = _mm_loadu_pd(xyz);
+ t2 = _mm_loadu_pd(xyz+2);
+ t3 = _mm_loadu_pd(xyz+4);
+ t4 = _mm_loadu_pd(xyz+6);
+ t5 = _mm_loadu_pd(xyz+8);
+ t6 = _mm_loadu_pd(xyz+10);
+
+ sxy = _mm_loadu_pd(xyz_shift);
+ sz = _mm_load_sd(xyz_shift+2);
+ szx = _mm_shuffle_pd(sz,sxy,_MM_SHUFFLE2(0,0));
+ syz = _mm_shuffle_pd(sxy,sz,_MM_SHUFFLE2(0,1));
+
+ t1 = _mm_add_pd(t1,sxy);
+ t2 = _mm_add_pd(t2,szx);
+ t3 = _mm_add_pd(t3,syz);
+ t4 = _mm_add_pd(t4,sxy);
+ t5 = _mm_add_pd(t5,szx);
+ t6 = _mm_add_pd(t6,syz);
+
+ *x1 = _mm_shuffle_pd(t1,t1,_MM_SHUFFLE2(0,0));
+ *y1 = _mm_shuffle_pd(t1,t1,_MM_SHUFFLE2(1,1));
+ *z1 = _mm_shuffle_pd(t2,t2,_MM_SHUFFLE2(0,0));
+ *x2 = _mm_shuffle_pd(t2,t2,_MM_SHUFFLE2(1,1));
+ *y2 = _mm_shuffle_pd(t3,t3,_MM_SHUFFLE2(0,0));
+ *z2 = _mm_shuffle_pd(t3,t3,_MM_SHUFFLE2(1,1));
+ *x3 = _mm_shuffle_pd(t4,t4,_MM_SHUFFLE2(0,0));
+ *y3 = _mm_shuffle_pd(t4,t4,_MM_SHUFFLE2(1,1));
+ *z3 = _mm_shuffle_pd(t5,t5,_MM_SHUFFLE2(0,0));
+ *x4 = _mm_shuffle_pd(t5,t5,_MM_SHUFFLE2(1,1));
+ *y4 = _mm_shuffle_pd(t6,t6,_MM_SHUFFLE2(0,0));
+ *z4 = _mm_shuffle_pd(t6,t6,_MM_SHUFFLE2(1,1));
+}
+
+
+
+
+static gmx_inline void
+gmx_mm_load_1rvec_1ptr_swizzle_pd(const double * gmx_restrict p1,
+ __m128d * gmx_restrict x, __m128d * gmx_restrict y, __m128d * gmx_restrict z)
+{
+ *x = _mm_load_sd(p1);
+ *y = _mm_load_sd(p1+1);
+ *z = _mm_load_sd(p1+2);
+}
+
+static gmx_inline void
+gmx_mm_load_3rvec_1ptr_swizzle_pd(const double * gmx_restrict p1,
+ __m128d * gmx_restrict x1, __m128d * gmx_restrict y1, __m128d * gmx_restrict z1,
+ __m128d * gmx_restrict x2, __m128d * gmx_restrict y2, __m128d * gmx_restrict z2,
+ __m128d * gmx_restrict x3, __m128d * gmx_restrict y3, __m128d * gmx_restrict z3)
+{
+ *x1 = _mm_load_sd(p1);
+ *y1 = _mm_load_sd(p1+1);
+ *z1 = _mm_load_sd(p1+2);
+ *x2 = _mm_load_sd(p1+3);
+ *y2 = _mm_load_sd(p1+4);
+ *z2 = _mm_load_sd(p1+5);
+ *x3 = _mm_load_sd(p1+6);
+ *y3 = _mm_load_sd(p1+7);
+ *z3 = _mm_load_sd(p1+8);
+}
+
+static gmx_inline void
+gmx_mm_load_4rvec_1ptr_swizzle_pd(const double * gmx_restrict p1,
+ __m128d * gmx_restrict x1, __m128d * gmx_restrict y1, __m128d * gmx_restrict z1,
+ __m128d * gmx_restrict x2, __m128d * gmx_restrict y2, __m128d * gmx_restrict z2,
+ __m128d * gmx_restrict x3, __m128d * gmx_restrict y3, __m128d * gmx_restrict z3,
+ __m128d * gmx_restrict x4, __m128d * gmx_restrict y4, __m128d * gmx_restrict z4)
+{
+ *x1 = _mm_load_sd(p1);
+ *y1 = _mm_load_sd(p1+1);
+ *z1 = _mm_load_sd(p1+2);
+ *x2 = _mm_load_sd(p1+3);
+ *y2 = _mm_load_sd(p1+4);
+ *z2 = _mm_load_sd(p1+5);
+ *x3 = _mm_load_sd(p1+6);
+ *y3 = _mm_load_sd(p1+7);
+ *z3 = _mm_load_sd(p1+8);
+ *x4 = _mm_load_sd(p1+9);
+ *y4 = _mm_load_sd(p1+10);
+ *z4 = _mm_load_sd(p1+11);
+}
+
+
+static gmx_inline void
+gmx_mm_load_1rvec_2ptr_swizzle_pd(const double * gmx_restrict ptrA,
+ const double * gmx_restrict ptrB,
+ __m128d * gmx_restrict x1, __m128d * gmx_restrict y1, __m128d * gmx_restrict z1)
+{
+ __m128d t1,t2,t3,t4;
+ t1 = _mm_loadu_pd(ptrA);
+ t2 = _mm_loadu_pd(ptrB);
+ t3 = _mm_load_sd(ptrA+2);
+ t4 = _mm_load_sd(ptrB+2);
+ GMX_MM_TRANSPOSE2_PD(t1,t2);
+ *x1 = t1;
+ *y1 = t2;
+ *z1 = _mm_unpacklo_pd(t3,t4);
+}
+
+
+static gmx_inline void
+gmx_mm_load_3rvec_2ptr_swizzle_pd(const double * gmx_restrict ptrA, const double * gmx_restrict ptrB,
+ __m128d * gmx_restrict x1, __m128d * gmx_restrict y1, __m128d * gmx_restrict z1,
+ __m128d * gmx_restrict x2, __m128d * gmx_restrict y2, __m128d * gmx_restrict z2,
+ __m128d * gmx_restrict x3, __m128d * gmx_restrict y3, __m128d * gmx_restrict z3)
+{
+ __m128d t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
+ t1 = _mm_loadu_pd(ptrA);
+ t2 = _mm_loadu_pd(ptrB);
+ t3 = _mm_loadu_pd(ptrA+2);
+ t4 = _mm_loadu_pd(ptrB+2);
+ t5 = _mm_loadu_pd(ptrA+4);
+ t6 = _mm_loadu_pd(ptrB+4);
+ t7 = _mm_loadu_pd(ptrA+6);
+ t8 = _mm_loadu_pd(ptrB+6);
+ t9 = _mm_load_sd(ptrA+8);
+ t10 = _mm_load_sd(ptrB+8);
+ GMX_MM_TRANSPOSE2_PD(t1,t2);
+ GMX_MM_TRANSPOSE2_PD(t3,t4);
+ GMX_MM_TRANSPOSE2_PD(t5,t6);
+ GMX_MM_TRANSPOSE2_PD(t7,t8);
+ *x1 = t1;
+ *y1 = t2;
+ *z1 = t3;
+ *x2 = t4;
+ *y2 = t5;
+ *z2 = t6;
+ *x3 = t7;
+ *y3 = t8;
+ *z3 = _mm_unpacklo_pd(t9,t10);
+}
+
+
+static gmx_inline void
+gmx_mm_load_4rvec_2ptr_swizzle_pd(const double * gmx_restrict ptrA, const double * gmx_restrict ptrB,
+ __m128d * gmx_restrict x1, __m128d * gmx_restrict y1, __m128d * gmx_restrict z1,
+ __m128d * gmx_restrict x2, __m128d * gmx_restrict y2, __m128d * gmx_restrict z2,
+ __m128d * gmx_restrict x3, __m128d * gmx_restrict y3, __m128d * gmx_restrict z3,
+ __m128d * gmx_restrict x4, __m128d * gmx_restrict y4, __m128d * gmx_restrict z4)
+{
+ __m128d t1,t2,t3,t4,t5,t6;
+ t1 = _mm_loadu_pd(ptrA);
+ t2 = _mm_loadu_pd(ptrB);
+ t3 = _mm_loadu_pd(ptrA+2);
+ t4 = _mm_loadu_pd(ptrB+2);
+ t5 = _mm_loadu_pd(ptrA+4);
+ t6 = _mm_loadu_pd(ptrB+4);
+ GMX_MM_TRANSPOSE2_PD(t1,t2);
+ GMX_MM_TRANSPOSE2_PD(t3,t4);
+ GMX_MM_TRANSPOSE2_PD(t5,t6);
+ *x1 = t1;
+ *y1 = t2;
+ *z1 = t3;
+ *x2 = t4;
+ *y2 = t5;
+ *z2 = t6;
+ t1 = _mm_loadu_pd(ptrA+6);
+ t2 = _mm_loadu_pd(ptrB+6);
+ t3 = _mm_loadu_pd(ptrA+8);
+ t4 = _mm_loadu_pd(ptrB+8);
+ t5 = _mm_loadu_pd(ptrA+10);
+ t6 = _mm_loadu_pd(ptrB+10);
+ GMX_MM_TRANSPOSE2_PD(t1,t2);
+ GMX_MM_TRANSPOSE2_PD(t3,t4);
+ GMX_MM_TRANSPOSE2_PD(t5,t6);
+ *x3 = t1;
+ *y3 = t2;
+ *z3 = t3;
+ *x4 = t4;
+ *y4 = t5;
+ *z4 = t6;
+}
+
+
+/* Routines to decrement rvec in memory, typically use for j particle force updates */
+static gmx_inline void
+gmx_mm_decrement_1rvec_1ptr_noswizzle_pd(double * gmx_restrict ptrA,
+ __m128d xy, __m128d z)
+{
+ __m128d t1,t2;
+
+ t1 = _mm_loadu_pd(ptrA);
+ t2 = _mm_load_sd(ptrA+2);
+
+ t1 = _mm_sub_pd(t1,xy);
+ t2 = _mm_sub_sd(t2,z);
+
+ _mm_storeu_pd(ptrA,t1);
+ _mm_store_sd(ptrA+2,t2);
+}
+
+static gmx_inline void
+gmx_mm_decrement_3rvec_1ptr_noswizzle_pd(double * gmx_restrict ptrA,
+ __m128d xy1, __m128d z1,
+ __m128d xy2, __m128d z2,
+ __m128d xy3, __m128d z3)
+{
+ __m128d t1,t2;
+ __m128d tA,tB,tC,tD,tE;
+
+ tA = _mm_loadu_pd(ptrA);
+ tB = _mm_loadu_pd(ptrA+2);
+ tC = _mm_loadu_pd(ptrA+4);
+ tD = _mm_loadu_pd(ptrA+6);
+ tE = _mm_load_sd(ptrA+8);
+
+ /* xy1: y1 x1 */
+ t1 = _mm_shuffle_pd(z1,xy2,_MM_SHUFFLE2(0,1)); /* x2 z1 */
+ t2 = _mm_shuffle_pd(xy2,z2,_MM_SHUFFLE2(0,1)); /* z2 y2 */
+ /* xy3: y3 x3 */
+
+ tA = _mm_sub_pd(tA,xy1);
+ tB = _mm_sub_pd(tB,t1);
+ tC = _mm_sub_pd(tC,t2);
+ tD = _mm_sub_pd(tD,xy3);
+ tE = _mm_sub_sd(tE,z3);
+
+ _mm_storeu_pd(ptrA,tA);
+ _mm_storeu_pd(ptrA+2,tB);
+ _mm_storeu_pd(ptrA+4,tC);
+ _mm_storeu_pd(ptrA+6,tD);
+ _mm_store_sd(ptrA+8,tE);
+}
+
+static gmx_inline void
+gmx_mm_decrement_4rvec_1ptr_noswizzle_pd(double * gmx_restrict ptrA,
+ __m128d xy1, __m128d z1,
+ __m128d xy2, __m128d z2,
+ __m128d xy3, __m128d z3,
+ __m128d xy4, __m128d z4)
+{
+ __m128d t1,t2,t3,t4;
+ __m128d tA,tB,tC,tD,tE,tF;
+
+ tA = _mm_loadu_pd(ptrA);
+ tB = _mm_loadu_pd(ptrA+2);
+ tC = _mm_loadu_pd(ptrA+4);
+ tD = _mm_loadu_pd(ptrA+6);
+ tE = _mm_loadu_pd(ptrA+8);
+ tF = _mm_loadu_pd(ptrA+10);
+
+ /* xy1: y1 x1 */
+ t1 = _mm_shuffle_pd(z1,xy2,_MM_SHUFFLE2(0,0)); /* x2 z1 */
+ t2 = _mm_shuffle_pd(xy2,z2,_MM_SHUFFLE2(0,1)); /* z2 y2 */
+ /* xy3: y3 x3 */
+ t3 = _mm_shuffle_pd(z3,xy4,_MM_SHUFFLE2(0,0)); /* x4 z3 */
+ t4 = _mm_shuffle_pd(xy4,z4,_MM_SHUFFLE2(0,1)); /* z4 y4 */
+
+ tA = _mm_sub_pd(tA,xy1);
+ tB = _mm_sub_pd(tB,t1);
+ tC = _mm_sub_pd(tC,t2);
+ tD = _mm_sub_pd(tD,xy3);
+ tE = _mm_sub_pd(tE,t3);
+ tF = _mm_sub_pd(tF,t4);
+
+ _mm_storeu_pd(ptrA,tA);
+ _mm_storeu_pd(ptrA+2,tB);
+ _mm_storeu_pd(ptrA+4,tC);
+ _mm_storeu_pd(ptrA+6,tD);
+ _mm_storeu_pd(ptrA+8,tE);
+ _mm_storeu_pd(ptrA+10,tF);
+}
+
+static gmx_inline void
+gmx_mm_decrement_1rvec_1ptr_swizzle_pd(double * gmx_restrict ptrA,
+ __m128d x1, __m128d y1, __m128d z1)
+{
+ __m128d t1,t2,t3;
+
+ t1 = _mm_load_sd(ptrA);
+ t2 = _mm_load_sd(ptrA+1);
+ t3 = _mm_load_sd(ptrA+2);
+
+ t1 = _mm_sub_sd(t1,x1);
+ t2 = _mm_sub_sd(t2,y1);
+ t3 = _mm_sub_sd(t3,z1);
+ _mm_store_sd(ptrA,t1);
+ _mm_store_sd(ptrA+1,t2);
+ _mm_store_sd(ptrA+2,t3);
+}
+
+
+static gmx_inline void
+gmx_mm_decrement_3rvec_1ptr_swizzle_pd(double * gmx_restrict ptrA,
+ __m128d x1, __m128d y1, __m128d z1,
+ __m128d x2, __m128d y2, __m128d z2,
+ __m128d x3, __m128d y3, __m128d z3)
+{
+ __m128d t1,t2,t3,t4,t5;
+
+ t1 = _mm_loadu_pd(ptrA);
+ t2 = _mm_loadu_pd(ptrA+2);
+ t3 = _mm_loadu_pd(ptrA+4);
+ t4 = _mm_loadu_pd(ptrA+6);
+ t5 = _mm_load_sd(ptrA+8);
+
+ x1 = _mm_unpacklo_pd(x1,y1);
+ z1 = _mm_unpacklo_pd(z1,x2);
+ y2 = _mm_unpacklo_pd(y2,z2);
+ x3 = _mm_unpacklo_pd(x3,y3);
+ /* nothing to be done for z3 */
+
+ t1 = _mm_sub_pd(t1,x1);
+ t2 = _mm_sub_pd(t2,z1);
+ t3 = _mm_sub_pd(t3,y2);
+ t4 = _mm_sub_pd(t4,x3);
+ t5 = _mm_sub_sd(t5,z3);
+ _mm_storeu_pd(ptrA,t1);
+ _mm_storeu_pd(ptrA+2,t2);
+ _mm_storeu_pd(ptrA+4,t3);
+ _mm_storeu_pd(ptrA+6,t4);
+ _mm_store_sd(ptrA+8,t5);
+}
+
+
+static gmx_inline void
+gmx_mm_decrement_4rvec_1ptr_swizzle_pd(double * gmx_restrict ptrA,
+ __m128d x1, __m128d y1, __m128d z1,
+ __m128d x2, __m128d y2, __m128d z2,
+ __m128d x3, __m128d y3, __m128d z3,
+ __m128d x4, __m128d y4, __m128d z4)
+{
+ __m128d t1,t2,t3,t4,t5,t6;
+
+ t1 = _mm_loadu_pd(ptrA);
+ t2 = _mm_loadu_pd(ptrA+2);
+ t3 = _mm_loadu_pd(ptrA+4);
+ t4 = _mm_loadu_pd(ptrA+6);
+ t5 = _mm_loadu_pd(ptrA+8);
+ t6 = _mm_loadu_pd(ptrA+10);
+
+ x1 = _mm_unpacklo_pd(x1,y1);
+ z1 = _mm_unpacklo_pd(z1,x2);
+ y2 = _mm_unpacklo_pd(y2,z2);
+ x3 = _mm_unpacklo_pd(x3,y3);
+ z3 = _mm_unpacklo_pd(z3,x4);
+ y4 = _mm_unpacklo_pd(y4,z4);
+
+ _mm_storeu_pd(ptrA, _mm_sub_pd( t1,x1 ));
+ _mm_storeu_pd(ptrA+2, _mm_sub_pd( t2,z1 ));
+ _mm_storeu_pd(ptrA+4, _mm_sub_pd( t3,y2 ));
+ _mm_storeu_pd(ptrA+6, _mm_sub_pd( t4,x3 ));
+ _mm_storeu_pd(ptrA+8, _mm_sub_pd( t5,z3 ));
+ _mm_storeu_pd(ptrA+10, _mm_sub_pd( t6,y4 ));
+}
+
+static gmx_inline void
+gmx_mm_decrement_1rvec_2ptr_swizzle_pd(double * gmx_restrict ptrA, double * gmx_restrict ptrB,
+ __m128d x1, __m128d y1, __m128d z1)
+{
+ __m128d t1,t2,t3,t4,t5,t6,t7;
+
+ t1 = _mm_loadu_pd(ptrA);
+ t2 = _mm_load_sd(ptrA+2);
+ t3 = _mm_loadu_pd(ptrB);
+ t4 = _mm_load_sd(ptrB+2);
+
+ t5 = _mm_unpacklo_pd(x1,y1);
+ t6 = _mm_unpackhi_pd(x1,y1);
+ t7 = _mm_unpackhi_pd(z1,z1);
+
+ t1 = _mm_sub_pd(t1,t5);
+ t2 = _mm_sub_sd(t2,z1);
+
+ t3 = _mm_sub_pd(t3,t6);
+ t4 = _mm_sub_sd(t4,t7);
+
+ _mm_storeu_pd(ptrA,t1);
+ _mm_store_sd(ptrA+2,t2);
+ _mm_storeu_pd(ptrB,t3);
+ _mm_store_sd(ptrB+2,t4);
+}
+
+static gmx_inline void
+gmx_mm_decrement_3rvec_2ptr_swizzle_pd(double * gmx_restrict ptrA, double * gmx_restrict ptrB,
+ __m128d x1, __m128d y1, __m128d z1,
+ __m128d x2, __m128d y2, __m128d z2,
+ __m128d x3, __m128d y3, __m128d z3)
+{
+ __m128d t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
+ __m128d tA,tB,tC,tD,tE,tF,tG,tH,tI;
+
+ t1 = _mm_loadu_pd(ptrA);
+ t2 = _mm_loadu_pd(ptrA+2);
+ t3 = _mm_loadu_pd(ptrA+4);
+ t4 = _mm_loadu_pd(ptrA+6);
+ t5 = _mm_load_sd(ptrA+8);
+ t6 = _mm_loadu_pd(ptrB);
+ t7 = _mm_loadu_pd(ptrB+2);
+ t8 = _mm_loadu_pd(ptrB+4);
+ t9 = _mm_loadu_pd(ptrB+6);
+ t10 = _mm_load_sd(ptrB+8);
+
+ tA = _mm_unpacklo_pd(x1,y1);
+ tB = _mm_unpackhi_pd(x1,y1);
+ tC = _mm_unpacklo_pd(z1,x2);
+ tD = _mm_unpackhi_pd(z1,x2);
+ tE = _mm_unpacklo_pd(y2,z2);
+ tF = _mm_unpackhi_pd(y2,z2);
+ tG = _mm_unpacklo_pd(x3,y3);
+ tH = _mm_unpackhi_pd(x3,y3);
+ tI = _mm_unpackhi_pd(z3,z3);
+
+ t1 = _mm_sub_pd(t1,tA);
+ t2 = _mm_sub_pd(t2,tC);
+ t3 = _mm_sub_pd(t3,tE);
+ t4 = _mm_sub_pd(t4,tG);
+ t5 = _mm_sub_sd(t5,z3);
+
+ t6 = _mm_sub_pd(t6,tB);
+ t7 = _mm_sub_pd(t7,tD);
+ t8 = _mm_sub_pd(t8,tF);
+ t9 = _mm_sub_pd(t9,tH);
+ t10 = _mm_sub_sd(t10,tI);
+
+ _mm_storeu_pd(ptrA,t1);
+ _mm_storeu_pd(ptrA+2,t2);
+ _mm_storeu_pd(ptrA+4,t3);
+ _mm_storeu_pd(ptrA+6,t4);
+ _mm_store_sd(ptrA+8,t5);
+ _mm_storeu_pd(ptrB,t6);
+ _mm_storeu_pd(ptrB+2,t7);
+ _mm_storeu_pd(ptrB+4,t8);
+ _mm_storeu_pd(ptrB+6,t9);
+ _mm_store_sd(ptrB+8,t10);
+}
+
+
+static gmx_inline void
+gmx_mm_decrement_4rvec_2ptr_swizzle_pd(double * gmx_restrict ptrA, double * gmx_restrict ptrB,
+ __m128d x1, __m128d y1, __m128d z1,
+ __m128d x2, __m128d y2, __m128d z2,
+ __m128d x3, __m128d y3, __m128d z3,
+ __m128d x4, __m128d y4, __m128d z4)
+{
+ __m128d t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12;
+ __m128d tA,tB,tC,tD,tE,tF,tG,tH,tI,tJ,tK,tL;
+
+ t1 = _mm_loadu_pd(ptrA);
+ t2 = _mm_loadu_pd(ptrA+2);
+ t3 = _mm_loadu_pd(ptrA+4);
+ t4 = _mm_loadu_pd(ptrA+6);
+ t5 = _mm_loadu_pd(ptrA+8);
+ t6 = _mm_loadu_pd(ptrA+10);
+ t7 = _mm_loadu_pd(ptrB);
+ t8 = _mm_loadu_pd(ptrB+2);
+ t9 = _mm_loadu_pd(ptrB+4);
+ t10 = _mm_loadu_pd(ptrB+6);
+ t11 = _mm_loadu_pd(ptrB+8);
+ t12 = _mm_loadu_pd(ptrB+10);
+
+ tA = _mm_unpacklo_pd(x1,y1);
+ tB = _mm_unpackhi_pd(x1,y1);
+ tC = _mm_unpacklo_pd(z1,x2);
+ tD = _mm_unpackhi_pd(z1,x2);
+ tE = _mm_unpacklo_pd(y2,z2);
+ tF = _mm_unpackhi_pd(y2,z2);
+ tG = _mm_unpacklo_pd(x3,y3);
+ tH = _mm_unpackhi_pd(x3,y3);
+ tI = _mm_unpacklo_pd(z3,x4);
+ tJ = _mm_unpackhi_pd(z3,x4);
+ tK = _mm_unpacklo_pd(y4,z4);
+ tL = _mm_unpackhi_pd(y4,z4);
+
+ t1 = _mm_sub_pd(t1,tA);
+ t2 = _mm_sub_pd(t2,tC);
+ t3 = _mm_sub_pd(t3,tE);
+ t4 = _mm_sub_pd(t4,tG);
+ t5 = _mm_sub_pd(t5,tI);
+ t6 = _mm_sub_pd(t6,tK);
+
+ t7 = _mm_sub_pd(t7,tB);
+ t8 = _mm_sub_pd(t8,tD);
+ t9 = _mm_sub_pd(t9,tF);
+ t10 = _mm_sub_pd(t10,tH);
+ t11 = _mm_sub_pd(t11,tJ);
+ t12 = _mm_sub_pd(t12,tL);
+
+ _mm_storeu_pd(ptrA, t1);
+ _mm_storeu_pd(ptrA+2,t2);
+ _mm_storeu_pd(ptrA+4,t3);
+ _mm_storeu_pd(ptrA+6,t4);
+ _mm_storeu_pd(ptrA+8,t5);
+ _mm_storeu_pd(ptrA+10,t6);
+ _mm_storeu_pd(ptrB, t7);
+ _mm_storeu_pd(ptrB+2,t8);
+ _mm_storeu_pd(ptrB+4,t9);
+ _mm_storeu_pd(ptrB+6,t10);
+ _mm_storeu_pd(ptrB+8,t11);
+ _mm_storeu_pd(ptrB+10,t12);
+}
+
+
+
+
+
+static gmx_inline void
+gmx_mm_update_iforce_1atom_swizzle_pd(__m128d fix1, __m128d fiy1, __m128d fiz1,
+ double * gmx_restrict fptr,
+ double * gmx_restrict fshiftptr)
+{
+ __m128d t1,t2,t3;
+
+ /* transpose data */
+ t1 = fix1;
+ fix1 = _mm_unpacklo_pd(fix1,fiy1); /* y0 x0 */
+ fiy1 = _mm_unpackhi_pd(t1,fiy1); /* y1 x1 */
+
+ fix1 = _mm_add_pd(fix1,fiy1);
+ fiz1 = _mm_add_sd( fiz1, _mm_unpackhi_pd(fiz1,fiz1 ));
+
+ _mm_storeu_pd( fptr, _mm_add_pd( _mm_loadu_pd(fptr), fix1 ));
+ _mm_store_sd( fptr+2, _mm_add_sd( _mm_load_sd(fptr+2), fiz1 ));
+
+ _mm_storeu_pd( fshiftptr, _mm_add_pd( _mm_loadu_pd(fshiftptr), fix1 ));
+ _mm_store_sd( fshiftptr+2, _mm_add_sd( _mm_load_sd(fshiftptr+2), fiz1 ));
+}
+
+static gmx_inline void
+gmx_mm_update_iforce_3atom_swizzle_pd(__m128d fix1, __m128d fiy1, __m128d fiz1,
+ __m128d fix2, __m128d fiy2, __m128d fiz2,
+ __m128d fix3, __m128d fiy3, __m128d fiz3,
+ double * gmx_restrict fptr,
+ double * gmx_restrict fshiftptr)
+{
+ __m128d t1,t2;
+
+ /* transpose data */
+ GMX_MM_TRANSPOSE2_PD(fix1,fiy1);
+ GMX_MM_TRANSPOSE2_PD(fiz1,fix2);
+ GMX_MM_TRANSPOSE2_PD(fiy2,fiz2);
+ t1 = fix3;
+ fix3 = _mm_unpacklo_pd(fix3,fiy3); /* y0 x0 */
+ fiy3 = _mm_unpackhi_pd(t1,fiy3); /* y1 x1 */
+
+ fix1 = _mm_add_pd(fix1,fiy1);
+ fiz1 = _mm_add_pd(fiz1,fix2);
+ fiy2 = _mm_add_pd(fiy2,fiz2);
+
+ fix3 = _mm_add_pd(fix3,fiy3);
+ fiz3 = _mm_add_sd( fiz3, _mm_unpackhi_pd(fiz3,fiz3));
+
+ _mm_storeu_pd( fptr, _mm_add_pd( _mm_loadu_pd(fptr), fix1 ));
+ _mm_storeu_pd( fptr+2, _mm_add_pd( _mm_loadu_pd(fptr+2), fiz1 ));
+ _mm_storeu_pd( fptr+4, _mm_add_pd( _mm_loadu_pd(fptr+4), fiy2 ));
+ _mm_storeu_pd( fptr+6, _mm_add_pd( _mm_loadu_pd(fptr+6), fix3 ));
+ _mm_store_sd( fptr+8, _mm_add_sd( _mm_load_sd(fptr+8), fiz3 ));
+
+ fix1 = _mm_add_pd(fix1,fix3);
+ t1 = _mm_shuffle_pd(fiz1,fiy2,_MM_SHUFFLE2(0,1));
+ fix1 = _mm_add_pd(fix1,t1); /* x and y sums */
+
+ t2 = _mm_shuffle_pd(fiy2,fiy2,_MM_SHUFFLE2(1,1));
+ fiz1 = _mm_add_sd(fiz1,fiz3);
+ fiz1 = _mm_add_sd(fiz1,t2); /* z sum */
+
+ _mm_storeu_pd( fshiftptr, _mm_add_pd( _mm_loadu_pd(fshiftptr), fix1 ));
+ _mm_store_sd( fshiftptr+2, _mm_add_sd( _mm_load_sd(fshiftptr+2), fiz1 ));
+}
+
+
+static gmx_inline void
+gmx_mm_update_iforce_4atom_swizzle_pd(__m128d fix1, __m128d fiy1, __m128d fiz1,
+ __m128d fix2, __m128d fiy2, __m128d fiz2,
+ __m128d fix3, __m128d fiy3, __m128d fiz3,
+ __m128d fix4, __m128d fiy4, __m128d fiz4,
+ double * gmx_restrict fptr,
+ double * gmx_restrict fshiftptr)
+{
+ __m128d t1,t2;
+
+ /* transpose data */
+ GMX_MM_TRANSPOSE2_PD(fix1,fiy1);
+ GMX_MM_TRANSPOSE2_PD(fiz1,fix2);
+ GMX_MM_TRANSPOSE2_PD(fiy2,fiz2);
+ GMX_MM_TRANSPOSE2_PD(fix3,fiy3);
+ GMX_MM_TRANSPOSE2_PD(fiz3,fix4);
+ GMX_MM_TRANSPOSE2_PD(fiy4,fiz4);
+
+ fix1 = _mm_add_pd(fix1,fiy1);
+ fiz1 = _mm_add_pd(fiz1,fix2);
+ fiy2 = _mm_add_pd(fiy2,fiz2);
+ fix3 = _mm_add_pd(fix3,fiy3);
+ fiz3 = _mm_add_pd(fiz3,fix4);
+ fiy4 = _mm_add_pd(fiy4,fiz4);
+
+ _mm_storeu_pd( fptr, _mm_add_pd( _mm_loadu_pd(fptr), fix1 ));
+ _mm_storeu_pd( fptr+2, _mm_add_pd( _mm_loadu_pd(fptr+2), fiz1 ));
+ _mm_storeu_pd( fptr+4, _mm_add_pd( _mm_loadu_pd(fptr+4), fiy2 ));
+ _mm_storeu_pd( fptr+6, _mm_add_pd( _mm_loadu_pd(fptr+6), fix3 ));
+ _mm_storeu_pd( fptr+8, _mm_add_pd( _mm_loadu_pd(fptr+8), fiz3 ));
+ _mm_storeu_pd( fptr+10, _mm_add_pd( _mm_loadu_pd(fptr+10), fiy4 ));
+
+ t1 = _mm_shuffle_pd(fiz1,fiy2,_MM_SHUFFLE2(0,1));
+ fix1 = _mm_add_pd(fix1,t1);
+ t2 = _mm_shuffle_pd(fiz3,fiy4,_MM_SHUFFLE2(0,1));
+ fix3 = _mm_add_pd(fix3,t2);
+ fix1 = _mm_add_pd(fix1,fix3); /* x and y sums */
+
+ fiz1 = _mm_add_sd(fiz1, _mm_unpackhi_pd(fiy2,fiy2));
+ fiz3 = _mm_add_sd(fiz3, _mm_unpackhi_pd(fiy4,fiy4));
+ fiz1 = _mm_add_sd(fiz1,fiz3); /* z sum */
+
+ _mm_storeu_pd( fshiftptr, _mm_add_pd( _mm_loadu_pd(fshiftptr), fix1 ));
+ _mm_store_sd( fshiftptr+2, _mm_add_sd( _mm_load_sd(fshiftptr+2), fiz1 ));
+}
+
+
+
+static gmx_inline void
+gmx_mm_update_1pot_pd(__m128d pot1, double * gmx_restrict ptrA)
+{
+ pot1 = _mm_add_pd(pot1, _mm_unpackhi_pd(pot1,pot1));
+ _mm_store_sd(ptrA,_mm_add_sd(pot1,_mm_load_sd(ptrA)));
+}
+
+static gmx_inline void
+gmx_mm_update_2pot_pd(__m128d pot1, double * gmx_restrict ptrA,
+ __m128d pot2, double * gmx_restrict ptrB)
+{
+ GMX_MM_TRANSPOSE2_PD(pot1,pot2);
+ pot1 = _mm_add_pd(pot1,pot2);
+ pot2 = _mm_unpackhi_pd(pot1,pot1);
+
+ _mm_store_sd(ptrA,_mm_add_sd(pot1,_mm_load_sd(ptrA)));
+ _mm_store_sd(ptrB,_mm_add_sd(pot2,_mm_load_sd(ptrB)));
+}
+
+
+#endif /* _kernelutil_x86_sse2_double_h_ */
--- /dev/null
+#!/usr/bin/python
+
+import sys
+import os
+sys.path.append ( "../preprocessor" )
+from gmxpreprocess import gmxpreprocess
+
+# "The happiest programs are programs that write other programs."
+#
+#
+# This script controls the generation of Gromacs nonbonded kernels.
+#
+# We no longer generate kernels on-the-fly, so this file is not run
+# during a Gromacs compile - only when we need to update the kernels (=rarely).
+#
+# To maximize performance, each combination of interactions in Gromacs
+# has a separate nonbonded kernel without conditionals in the code.
+# To avoid writing hundreds of different routines for each architecture,
+# we instead use a custom preprocessor so we can encode the conditionals
+# and expand for-loops (e.g, for water-water interactions)
+# from a general kernel template. While that file will contain quite a
+# few preprocessor directives, it is still an order of magnitude easier
+# to maintain than ~200 different kernels (not to mention it avoids bugs).
+#
+# To actually generate the kernels, this program iteratively calls the
+# preprocessor with different define settings corresponding to all
+# combinations of coulomb/van-der-Waals/geometry options.
+#
+# A main goal in the design was to make this new generator _general_. For
+# this reason we have used a lot of different fields to identify a particular
+# kernel and interaction. Basically, each kernel will have a name like
+#
+# nbkernel_ElecXX_VdwYY_GeomZZ_VF_QQ()
+#
+# Where XX/YY/ZZ/VF are strings to identify what the kernel computes.
+#
+# Elec/Vdw describe the type of interaction for electrostatics and van der Waals.
+# The geometry settings correspond e.g. to water-water or water-particle kernels,
+# and finally the VF setting is V,F,or VF depending on whether we calculate
+# only the potential, only the force, or both of them. The final string (QQ)
+# is the architecture/language/optimization of the kernel.
+#
+Arch = 'sse2_double'
+
+# Explanation of the 'properties':
+#
+# It is cheap to compute r^2, and the kernels require various other functions of r for
+# different kinds of interaction. Depending on the needs of the kernel and the available
+# processor instructions, this will be done in different ways.
+#
+# 'rinv' means we need 1/r, which is calculated as 1/sqrt(r^2).
+# 'rinvsq' means we need 1/(r*r). This is calculated as rinv*rinv if we already did rinv, otherwise 1/r^2.
+# 'r' is similarly calculated as r^2*rinv when needed
+# 'table' means the interaction is tabulated, in which case we will calculate a table index before the interaction
+# 'shift' means the interaction will be modified by a constant to make it zero at the cutoff.
+# 'cutoff' means the interaction is set to 0.0 outside the cutoff
+#
+
+FileHeader = \
+'/*\n' \
+' * Note: this file was generated by the Gromacs '+Arch+' kernel generator.\n' \
+' *\n' \
+' * This source code is part of\n' \
+' *\n' \
+' * G R O M A C S\n' \
+' *\n' \
+' * Copyright (c) 2001-2012, The GROMACS Development Team\n' \
+' *\n' \
+' * Gromacs is a library for molecular simulation and trajectory analysis,\n' \
+' * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for\n' \
+' * a full list of developers and information, check out http://www.gromacs.org\n' \
+' *\n' \
+' * This program is free software; you can redistribute it and/or modify it under\n' \
+' * the terms of the GNU Lesser General Public License as published by the Free\n' \
+' * Software Foundation; either version 2 of the License, or (at your option) any\n' \
+' * later version.\n' \
+' *\n' \
+' * To help fund GROMACS development, we humbly ask that you cite\n' \
+' * the papers people have written on it - you can find them on the website.\n' \
+' */\n'
+
+###############################################
+# ELECTROSTATICS
+# Interactions and flags for them
+###############################################
+ElectrostaticsList = {
+ 'None' : [],
+ 'Coulomb' : ['rinv','rinvsq'],
+ 'ReactionField' : ['rinv','rinvsq'],
+ 'GeneralizedBorn' : ['rinv','r'],
+ 'CubicSplineTable' : ['rinv','r','table'],
+ 'Ewald' : ['rinv','rinvsq','r'],
+}
+
+
+###############################################
+# VAN DER WAALS
+# Interactions and flags for them
+###############################################
+VdwList = {
+ 'None' : [],
+ 'LennardJones' : ['rinvsq'],
+# 'Buckingham' : ['rinv','rinvsq','r'], # Disabled for sse2 to reduce number of kernels and simply the template
+ 'CubicSplineTable' : ['rinv','r','table'],
+}
+
+
+###############################################
+# MODIFIERS
+# Different ways to adjust/modify interactions to conserve energy
+###############################################
+ModifierList = {
+ 'None' : [],
+ 'ExactCutoff' : ['exactcutoff'], # Zero the interaction outside the cutoff, used for reaction-field-zero
+ 'PotentialShift' : ['shift','exactcutoff'],
+ 'PotentialSwitch' : ['rinv','r','switch','exactcutoff']
+}
+
+
+###############################################
+# GEOMETRY COMBINATIONS
+###############################################
+GeometryNameList = [
+ [ 'Particle' , 'Particle' ],
+ [ 'Water3' , 'Particle' ],
+ [ 'Water3' , 'Water3' ],
+ [ 'Water4' , 'Particle' ],
+ [ 'Water4' , 'Water4' ]
+]
+
+
+###############################################
+# POTENTIAL / FORCE
+###############################################
+VFList = [
+ 'PotentialAndForce',
+# 'Potential', # Not used yet
+ 'Force'
+]
+
+
+###############################################
+# GEOMETRY PROPERTIES
+###############################################
+# Dictionaries with lists telling which interactions are present
+# 1,2,3 means particles 1,2,3 (but not 0) have electrostatics!
+GeometryElectrostatics = {
+ 'Particle' : [ 0 ],
+ 'Particle2' : [ 0 , 1 ],
+ 'Particle3' : [ 0 , 1 , 2 ],
+ 'Particle4' : [ 0 , 1 , 2 , 3 ],
+ 'Water3' : [ 0 , 1 , 2 ],
+ 'Water4' : [ 1 , 2 , 3 ]
+}
+
+GeometryVdw = {
+ 'Particle' : [ 0 ],
+ 'Particle2' : [ 0 , 1 ],
+ 'Particle3' : [ 0 , 1 , 2 ],
+ 'Particle4' : [ 0 , 1 , 2 , 3 ],
+ 'Water3' : [ 0 ],
+ 'Water4' : [ 0 ]
+}
+
+
+
+
+# Dictionary to abbreviate all strings (mixed from all the lists)
+Abbreviation = {
+ 'None' : 'None',
+ 'Coulomb' : 'Coul',
+ 'Ewald' : 'Ew',
+ 'ReactionField' : 'RF',
+ 'GeneralizedBorn' : 'GB',
+ 'CubicSplineTable' : 'CSTab',
+ 'LennardJones' : 'LJ',
+ 'Buckingham' : 'Bham',
+ 'PotentialShift' : 'Sh',
+ 'PotentialSwitch' : 'Sw',
+ 'ExactCutoff' : 'Cut',
+ 'PotentialAndForce' : 'VF',
+ 'Potential' : 'V',
+ 'Force' : 'F',
+ 'Water3' : 'W3',
+ 'Water4' : 'W4',
+ 'Particle' : 'P1',
+ 'Particle2' : 'P2',
+ 'Particle3' : 'P3',
+ 'Particle4' : 'P4'
+}
+
+
+###############################################
+# Functions
+###############################################
+
+# Return a string with the kernel name from current settings
+def MakeKernelFileName(KernelElec,KernelElecMod,KernelVdw,KernelVdwMod,KernelGeom):
+ ElecStr = 'Elec' + Abbreviation[KernelElec]
+ if(KernelElecMod!='None'):
+ ElecStr = ElecStr + Abbreviation[KernelElecMod]
+ VdwStr = 'Vdw' + Abbreviation[KernelVdw]
+ if(KernelVdwMod!='None'):
+ VdwStr = VdwStr + Abbreviation[KernelVdwMod]
+ GeomStr = 'Geom' + Abbreviation[KernelGeom[0]] + Abbreviation[KernelGeom[1]]
+ return 'nb_kernel_' + ElecStr + '_' + VdwStr + '_' + GeomStr + '_' + Arch
+
+def MakeKernelName(KernelElec,KernelElecMod,KernelVdw,KernelVdwMod,KernelGeom,KernelVF):
+ ElecStr = 'Elec' + Abbreviation[KernelElec]
+ if(KernelElecMod!='None'):
+ ElecStr = ElecStr + Abbreviation[KernelElecMod]
+ VdwStr = 'Vdw' + Abbreviation[KernelVdw]
+ if(KernelVdwMod!='None'):
+ VdwStr = VdwStr + Abbreviation[KernelVdwMod]
+ GeomStr = 'Geom' + Abbreviation[KernelGeom[0]] + Abbreviation[KernelGeom[1]]
+ VFStr = Abbreviation[KernelVF]
+ return 'nb_kernel_' + ElecStr + '_' + VdwStr + '_' + GeomStr + '_' + VFStr + '_' + Arch
+
+# Return a string with a declaration to use for the kernel;
+# this will be a sequence of string combinations as well as the actual function name
+# Dont worry about field widths - that is just pretty-printing for the header!
+def MakeKernelDecl(KernelName,KernelElec,KernelElecMod,KernelVdw,KernelVdwMod,KernelGeom,KernelOther,KernelVF):
+ KernelStr = '\"'+KernelName+'\"'
+ ArchStr = '\"'+Arch+'\"'
+ ElecStr = '\"'+KernelElec+'\"'
+ ElecModStr = '\"'+KernelElecMod+'\"'
+ VdwStr = '\"'+KernelVdw+'\"'
+ VdwModStr = '\"'+KernelVdwMod+'\"'
+ GeomStr = '\"'+KernelGeom[0]+KernelGeom[1]+'\"'
+ OtherStr = '\"'+KernelOther+'\"'
+ VFStr = '\"'+KernelVF+'\"'
+
+ ThisSpec = ArchStr+', '+ElecStr+', '+ElecModStr+', '+VdwStr+', '+VdwModStr+', '+GeomStr+', '+OtherStr+', '+VFStr
+ ThisDecl = ' { '+KernelName+', '+KernelStr+', '+ThisSpec+' }'
+ return ThisDecl
+
+
+# Returns 1 if this kernel should be created, 0 if we should skip it
+# This routine is not critical - it is not the end of the world if we create more kernels,
+# but since the number is pretty large we save both space and compile-time by reducing it a bit.
+def KeepKernel(KernelElec,KernelElecMod,KernelVdw,KernelVdwMod,KernelGeom,KernelVF):
+
+ # No need for kernels without interactions
+ if(KernelElec=='None' and KernelVdw=='None'):
+ return 0
+
+ # No need for modifiers without interactions
+ if((KernelElec=='None' and KernelElecMod!='None') or (KernelVdw=='None' and KernelVdwMod!='None')):
+ return 0
+
+ # No need for LJ-only water optimization, or water optimization with implicit solvent.
+ if('Water' in KernelGeom[0] and (KernelElec=='None' or 'GeneralizedBorn' in KernelElec)):
+ return 0
+
+ # Non-matching table settings are pointless
+ if( ('Table' in KernelElec) and ('Table' in KernelVdw) and KernelElec!=KernelVdw ):
+ return 0
+
+ # Try to reduce the number of different switch/shift options to get a reasonable number of kernels
+ # For electrostatics, reaction-field can use 'exactcutoff', and ewald can use switch or shift.
+ if(KernelElecMod=='ExactCutoff' and KernelElec!='ReactionField'):
+ return 0
+ if(KernelElecMod in ['PotentialShift','PotentialSwitch'] and KernelElec!='Ewald'):
+ return 0
+ # For Vdw, we support switch and shift for Lennard-Jones/Buckingham
+ if((KernelVdwMod=='ExactCutoff') or
+ (KernelVdwMod in ['PotentialShift','PotentialSwitch'] and KernelVdw not in ['LennardJones','Buckingham'])):
+ return 0
+
+ # Choose either switch or shift and don't mix them...
+ if((KernelElecMod=='PotentialShift' and KernelVdwMod=='PotentialSwitch') or
+ (KernelElecMod=='PotentialSwitch' and KernelVdwMod=='PotentialShift')):
+ return 0
+
+ # Don't use a Vdw kernel with a modifier if the electrostatics one does not have one
+ if(KernelElec!='None' and KernelElecMod=='None' and KernelVdwMod!='None'):
+ return 0
+
+ # Don't use an electrostatics kernel with a modifier if the vdw one does not have one,
+ # unless the electrostatics one is reaction-field with exact cutoff.
+ if(KernelVdw!='None' and KernelVdwMod=='None' and KernelElecMod!='None'):
+ if(KernelElec=='ReactionField' and KernelVdw!='CubicSplineTable'):
+ return 0
+ elif(KernelElec!='ReactionField'):
+ return 0
+
+ return 1
+
+
+
+#
+# The preprocessor will automatically expand the interactions for water and other
+# geometries inside the kernel, but to get this right we need to setup a couple
+# of defines - we do them in a separate routine to keep the main loop clean.
+#
+# While this routine might look a bit complex it is actually quite straightforward,
+# and the best news is that you wont have to modify _anything_ for a new geometry
+# as long as you correctly define its Electrostatics/Vdw geometry in the lists above!
+#
+def SetDefines(KernelElec,KernelElecMod,KernelVdw,KernelVdwMod,KernelGeom,KernelVF,defines):
+ # What is the _name_ for the i/j group geometry?
+ igeometry = KernelGeom[0]
+ jgeometry = KernelGeom[1]
+ # define so we can access it in the source when the preprocessor runs
+ defines['GEOMETRY_I'] = igeometry
+ defines['GEOMETRY_J'] = jgeometry
+
+ # For the i/j groups, extract a python list of which sites have electrostatics
+ # For SPC/TIP3p this will be [1,1,1], while TIP4p (no elec on first site) will be [0,1,1,1]
+ ielec = GeometryElectrostatics[igeometry]
+ jelec = GeometryElectrostatics[jgeometry]
+ # Zero out the corresponding lists in case we dont do Elec
+ if(KernelElec=='None'):
+ ielec = []
+ jelec = []
+
+ # Extract similar interaction lists for Vdw interactions (example for SPC: [1,0,0])
+ iVdw = GeometryVdw[igeometry]
+ jVdw = GeometryVdw[jgeometry]
+
+ # Zero out the corresponding lists in case we dont do Vdw
+ if(KernelVdw=='None'):
+ iVdw = []
+ jVdw = []
+
+ # iany[] and jany[] contains lists of the particles actually used (for interactions) in this kernel
+ iany = list(set(ielec+iVdw)) # convert to+from set to make elements unique
+ jany = list(set(jelec+jVdw))
+
+ defines['PARTICLES_ELEC_I'] = ielec
+ defines['PARTICLES_ELEC_J'] = jelec
+ defines['PARTICLES_VDW_I'] = iVdw
+ defines['PARTICLES_VDW_J'] = jVdw
+ defines['PARTICLES_I'] = iany
+ defines['PARTICLES_J'] = jany
+
+ # elecij,Vdwij are sets with pairs of particles for which the corresponding interaction is done
+ # (and anyij again corresponds to either electrostatics or Vdw)
+ elecij = []
+ Vdwij = []
+ anyij = []
+
+ for i in ielec:
+ for j in jelec:
+ elecij.append([i,j])
+
+ for i in iVdw:
+ for j in jVdw:
+ Vdwij.append([i,j])
+
+ for i in iany:
+ for j in jany:
+ if [i,j] in elecij or [i,j] in Vdwij:
+ anyij.append([i,j])
+
+ defines['PAIRS_IJ'] = anyij
+
+ # Make an 2d list-of-distance-properties-to-calculate for i,j
+ ni = max(iany)+1
+ nj = max(jany)+1
+ # Each element properties[i][j] is an empty list
+ properties = [ [ [] for j in range(0,nj) ] for i in range (0,ni) ]
+ # Add properties to each set
+ for i in range(0,ni):
+ for j in range(0,nj):
+ if [i,j] in elecij:
+ properties[i][j] = properties[i][j] + ['electrostatics'] + ElectrostaticsList[KernelElec] + ModifierList[KernelElecMod]
+ if [i,j] in Vdwij:
+ properties[i][j] = properties[i][j] + ['vdw'] + VdwList[KernelVdw] + ModifierList[KernelVdwMod]
+ # Add rinv if we need r
+ if 'r' in properties[i][j]:
+ properties[i][j] = properties[i][j] + ['rinv']
+ # Add rsq if we need rinv or rinsq
+ if 'rinv' in properties[i][j] or 'rinvsq' in properties[i][j]:
+ properties[i][j] = properties[i][j] + ['rsq']
+
+ defines['INTERACTION_FLAGS'] = properties
+
+
+
+def PrintStatistics(ratio):
+ ratio = 100.0*ratio
+ print '\rGenerating %s nonbonded kernels... %5.1f%%' % (Arch,ratio),
+ sys.stdout.flush()
+
+
+
+defines = {}
+kerneldecl = []
+
+cnt = 0.0
+nelec = len(ElectrostaticsList)
+nVdw = len(VdwList)
+nmod = len(ModifierList)
+ngeom = len(GeometryNameList)
+
+ntot = nelec*nmod*nVdw*nmod*ngeom
+
+numKernels = 0
+
+fpdecl = open('nb_kernel_' + Arch + '.c','w')
+fpdecl.write( FileHeader )
+fpdecl.write( '#ifndef nb_kernel_' + Arch + '_h\n' )
+fpdecl.write( '#define nb_kernel_' + Arch + '_h\n\n' )
+fpdecl.write( '#include "../nb_kernel.h"\n\n' )
+
+for KernelElec in ElectrostaticsList:
+ defines['KERNEL_ELEC'] = KernelElec
+
+ for KernelElecMod in ModifierList:
+ defines['KERNEL_MOD_ELEC'] = KernelElecMod
+
+ for KernelVdw in VdwList:
+ defines['KERNEL_VDW'] = KernelVdw
+
+ for KernelVdwMod in ModifierList:
+ defines['KERNEL_MOD_VDW'] = KernelVdwMod
+
+ for KernelGeom in GeometryNameList:
+
+ cnt += 1
+ KernelFilename = MakeKernelFileName(KernelElec,KernelElecMod,KernelVdw,KernelVdwMod,KernelGeom) + '.c'
+ fpkernel = open(KernelFilename,'w')
+ defines['INCLUDE_HEADER'] = 1 # Include header first time in new file
+ DoHeader = 1
+
+ for KernelVF in VFList:
+
+ KernelName = MakeKernelName(KernelElec,KernelElecMod,KernelVdw,KernelVdwMod,KernelGeom,KernelVF)
+
+ defines['KERNEL_NAME'] = KernelName
+ defines['KERNEL_VF'] = KernelVF
+
+ # Check if this is a valid/sane/usable combination
+ if not KeepKernel(KernelElec,KernelElecMod,KernelVdw,KernelVdwMod,KernelGeom,KernelVF):
+ continue;
+
+ # The overall kernel settings determine what the _kernel_ calculates, but for the water
+ # kernels this does not mean that every pairwise interaction has e.g. Vdw interactions.
+ # This routine sets defines of what to calculate for each pair of particles in those cases.
+ SetDefines(KernelElec,KernelElecMod,KernelVdw,KernelVdwMod,KernelGeom,KernelVF,defines)
+
+ if(DoHeader==1):
+ fpkernel.write( FileHeader )
+
+ gmxpreprocess('nb_kernel_template_' + Arch + '.pre', KernelName+'.tmp' , defines, force=1,contentType='C')
+ numKernels = numKernels + 1
+
+ defines['INCLUDE_HEADER'] = 0 # Header has been included once now
+ DoHeader=0
+
+ # Append temp file contents to the common kernelfile
+ fptmp = open(KernelName+'.tmp','r')
+ fpkernel.writelines(fptmp.readlines())
+ fptmp.close()
+ os.remove(KernelName+'.tmp')
+
+ # Add a declaration for this kernel
+ fpdecl.write('nb_kernel_t ' + KernelName + ';\n');
+
+ # Add declaration to the buffer
+ KernelOther=''
+ kerneldecl.append(MakeKernelDecl(KernelName,KernelElec,KernelElecMod,KernelVdw,KernelVdwMod,KernelGeom,KernelOther,KernelVF))
+
+ filesize = fpkernel.tell()
+ fpkernel.close()
+ if(filesize==0):
+ os.remove(KernelFilename)
+
+ PrintStatistics(cnt/ntot)
+ pass
+ pass
+ pass
+ pass
+pass
+
+# Write out the list of settings and corresponding kernels to the declaration file
+fpdecl.write( '\n\n' )
+fpdecl.write( 'nb_kernel_info_t\n' )
+fpdecl.write( 'kernellist_'+Arch+'[] =\n' )
+fpdecl.write( '{\n' )
+for decl in kerneldecl[0:-1]:
+ fpdecl.write( decl + ',\n' )
+fpdecl.write( kerneldecl[-1] + '\n' )
+fpdecl.write( '};\n\n' )
+fpdecl.write( 'int\n' )
+fpdecl.write( 'kernellist_'+Arch+'_size = sizeof(kernellist_'+Arch+')/sizeof(kernellist_'+Arch+'[0]);\n\n')
+fpdecl.write( '#endif\n')
+fpdecl.close()
+++ /dev/null
-/*
- * Copyright (c) Erik Lindahl, David van der Spoel 2003
- *
- * This file is generated automatically at compile time
- * by the program mknb in the Gromacs distribution.
- *
- * Options used when generation this file:
- * Language: c
- * Precision: double
- * Threads: no
- * Software invsqrt: yes
- * Prefetch forces: no
- * Comments: no
- */
-#ifdef HAVE_CONFIG_H
-#include<config.h>
-#endif
-#include<math.h>
-#include<vec.h>
-
-#include <emmintrin.h>
-
-#include <gmx_sse2_double.h>
-
-/* get gmx_gbdata_t */
-#include "../nb_kernel.h"
-
-
-void nb_kernel400_sse2_double(int * p_nri,
- int * iinr,
- int * jindex,
- int * jjnr,
- int * shift,
- double * shiftvec,
- double * fshift,
- int * gid,
- double * pos,
- double * faction,
- double * charge,
- double * p_facel,
- double * p_krf,
- double * p_crf,
- double * vc,
- int * type,
- int * p_ntype,
- double * vdwparam,
- double * vvdw,
- double * p_tabscale,
- double * VFtab,
- double * invsqrta,
- double * dvda,
- double * p_gbtabscale,
- double * GBtab,
- int * p_nthreads,
- int * count,
- void * mtx,
- int * outeriter,
- int * inneriter,
- double * work)
-{
- int nri,nthreads;
- int n,ii,is3,ii3,k,nj0,nj1,ggid;
- double shX,shY,shZ;
- int jnrA,jnrB;
- int j3A,j3B;
- gmx_gbdata_t *gbdata;
- double * gpol;
-
- __m128d iq,qq,jq,isai;
- __m128d ix,iy,iz;
- __m128d jx,jy,jz;
- __m128d dx,dy,dz;
- __m128d vctot,vgbtot,dvdasum,gbfactor;
- __m128d fix,fiy,fiz,tx,ty,tz,rsq;
- __m128d rinv,isaj,isaprod;
- __m128d vcoul,fscal,gbscale;
- __m128d rinvsq,r,rtab;
- __m128d eps,Y,F,G,H;
- __m128d vgb,fijGB,dvdatmp;
- __m128d facel,gbtabscale,dvdaj;
- __m128i n0, nnn;
-
- const __m128d neg = _mm_set1_pd(-1.0);
- const __m128d zero = _mm_set1_pd(0.0);
- const __m128d minushalf = _mm_set1_pd(-0.5);
- const __m128d two = _mm_set1_pd(2.0);
-
- gbdata = (gmx_gbdata_t *)work;
- gpol = gbdata->gpol;
-
- nri = *p_nri;
-
- gbfactor = _mm_set1_pd( - ((1.0/gbdata->epsilon_r) - (1.0/gbdata->gb_epsilon_solvent)));
- gbtabscale = _mm_load1_pd(p_gbtabscale);
- facel = _mm_load1_pd(p_facel);
-
- nj1 = 0;
- jnrA = jnrB = 0;
- j3A = j3B = 0;
- jx = _mm_setzero_pd();
- jy = _mm_setzero_pd();
- jz = _mm_setzero_pd();
-
- for(n=0;n<nri;n++)
- {
- is3 = 3*shift[n];
- shX = shiftvec[is3];
- shY = shiftvec[is3+1];
- shZ = shiftvec[is3+2];
- nj0 = jindex[n];
- nj1 = jindex[n+1];
- ii = iinr[n];
- ii3 = 3*ii;
-
- ix = _mm_set1_pd(shX+pos[ii3+0]);
- iy = _mm_set1_pd(shY+pos[ii3+1]);
- iz = _mm_set1_pd(shZ+pos[ii3+2]);
-
- iq = _mm_load1_pd(charge+ii);
- iq = _mm_mul_pd(iq,facel);
-
- isai = _mm_load1_pd(invsqrta+ii);
-
- vctot = _mm_setzero_pd();
- vgbtot = _mm_setzero_pd();
- dvdasum = _mm_setzero_pd();
- fix = _mm_setzero_pd();
- fiy = _mm_setzero_pd();
- fiz = _mm_setzero_pd();
-
- for(k=nj0;k<nj1-1; k+=2)
- {
- jnrA = jjnr[k];
- jnrB = jjnr[k+1];
-
- j3A = jnrA * 3;
- j3B = jnrB * 3;
-
- GMX_MM_LOAD_1RVEC_2POINTERS_PD(pos+j3A,pos+j3B,jx,jy,jz);
-
- dx = _mm_sub_pd(ix,jx);
- dy = _mm_sub_pd(iy,jy);
- dz = _mm_sub_pd(iz,jz);
-
- rsq = gmx_mm_calc_rsq_pd(dx,dy,dz);
-
- rinv = gmx_mm_invsqrt_pd(rsq);
- rinvsq = _mm_mul_pd(rinv,rinv);
-
- /***********************************/
- /* INTERACTION SECTION STARTS HERE */
- /***********************************/
- GMX_MM_LOAD_2VALUES_PD(charge+jnrA,charge+jnrB,jq);
- GMX_MM_LOAD_2VALUES_PD(invsqrta+jnrA,invsqrta+jnrB,isaj);
-
- isaprod = _mm_mul_pd(isai,isaj);
- qq = _mm_mul_pd(iq,jq);
- vcoul = _mm_mul_pd(qq,rinv);
- fscal = _mm_mul_pd(vcoul,rinv);
- vctot = _mm_add_pd(vctot,vcoul);
-
- /* Polarization interaction */
- qq = _mm_mul_pd(qq,_mm_mul_pd(isaprod,gbfactor));
- gbscale = _mm_mul_pd(isaprod,gbtabscale);
-
- /* Calculate GB table index */
- r = _mm_mul_pd(rsq,rinv);
- rtab = _mm_mul_pd(r,gbscale);
-
- n0 = _mm_cvttpd_epi32(rtab);
- eps = _mm_sub_pd(rtab,_mm_cvtepi32_pd(n0));
- nnn = _mm_slli_epi32(n0,2);
-
- /* the tables are 16-byte aligned, so we can use _mm_load_pd */
- Y = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,0)));
- F = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,1)));
- GMX_MM_TRANSPOSE2_PD(Y,F);
- G = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,0))+2);
- H = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,1))+2);
- GMX_MM_TRANSPOSE2_PD(G,H);
-
- G = _mm_mul_pd(G,eps);
- H = _mm_mul_pd(H, _mm_mul_pd(eps,eps) );
- F = _mm_add_pd(F, _mm_add_pd( G , H ) );
- Y = _mm_add_pd(Y, _mm_mul_pd(F, eps));
- F = _mm_add_pd(F, _mm_add_pd(G , _mm_mul_pd(H,two)));
- vgb = _mm_mul_pd(Y, qq);
- fijGB = _mm_mul_pd(F, _mm_mul_pd(qq,gbscale));
-
- dvdatmp = _mm_mul_pd(_mm_add_pd(vgb, _mm_mul_pd(fijGB,r)) , minushalf);
-
- vgbtot = _mm_add_pd(vgbtot, vgb);
-
- dvdasum = _mm_add_pd(dvdasum, dvdatmp);
- dvdatmp = _mm_mul_pd(dvdatmp, _mm_mul_pd(isaj,isaj));
-
- GMX_MM_INCREMENT_2VALUES_PD(dvda+jnrA,dvda+jnrB,dvdatmp);
-
- fscal = _mm_mul_pd( _mm_sub_pd( fscal, fijGB),rinv );
-
- /***********************************/
- /* INTERACTION SECTION ENDS HERE */
- /***********************************/
-
- /* Calculate temporary vectorial force */
- tx = _mm_mul_pd(fscal,dx);
- ty = _mm_mul_pd(fscal,dy);
- tz = _mm_mul_pd(fscal,dz);
-
- /* Increment i atom force */
- fix = _mm_add_pd(fix,tx);
- fiy = _mm_add_pd(fiy,ty);
- fiz = _mm_add_pd(fiz,tz);
-
- /* Store j forces back */
- GMX_MM_DECREMENT_1RVEC_2POINTERS_PD(faction+j3A,faction+j3B,tx,ty,tz);
- }
-
- /* In double precision, offset can only be either 0 or 1 */
- if(k<nj1)
- {
- jnrA = jjnr[k];
- j3A = jnrA * 3;
-
- GMX_MM_LOAD_1RVEC_1POINTER_PD(pos+j3A,jx,jy,jz);
-
- dx = _mm_sub_sd(ix,jx);
- dy = _mm_sub_sd(iy,jy);
- dz = _mm_sub_sd(iz,jz);
-
- rsq = gmx_mm_calc_rsq_pd(dx,dy,dz);
-
- rinv = gmx_mm_invsqrt_pd(rsq);
- rinvsq = _mm_mul_sd(rinv,rinv);
-
- /* These reason for zeroing these variables here is for fixing bug 585
- * What happens is that __m128d _mm_add_sd(a,b) gives back r0=a[0]+b[0],
- * and r1=0, but it should be r1=a[1].
- * This might be a compiler issue (tested with gcc-4.1.3 and -O3).
- * To work around it, we zero these variables and use _mm_add_pd (**) instead
- * Note that the only variables that get affected are the energies since
- * the total sum needs to be correct
- */
- vgb = _mm_setzero_pd();
- vcoul = _mm_setzero_pd();
- dvdatmp = _mm_setzero_pd();
-
- /***********************************/
- /* INTERACTION SECTION STARTS HERE */
- /***********************************/
- GMX_MM_LOAD_1VALUE_PD(charge+jnrA,jq);
- GMX_MM_LOAD_1VALUE_PD(invsqrta+jnrA,isaj);
-
- isaprod = _mm_mul_sd(isai,isaj);
- qq = _mm_mul_sd(jq,iq);
- vcoul = _mm_mul_sd(qq,rinv);
- fscal = _mm_mul_sd(vcoul,rinv);
- vctot = _mm_add_pd(vctot,vcoul); /* (**) */
-
- /* Polarization interaction */
- qq = _mm_mul_sd(qq,_mm_mul_sd(isaprod,gbfactor));
- gbscale = _mm_mul_sd(isaprod,gbtabscale);
-
- /* Calculate GB table index */
- r = _mm_mul_sd(rsq,rinv);
- rtab = _mm_mul_sd(r,gbscale);
-
- n0 = _mm_cvttpd_epi32(rtab);
- eps = _mm_sub_sd(rtab,_mm_cvtepi32_pd(n0));
- nnn = _mm_slli_epi32(n0,2);
-
- /* the tables are 16-byte aligned, so we can use _mm_load_pd */
- Y = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,0)));
- F = _mm_setzero_pd();
- GMX_MM_TRANSPOSE2_PD(Y,F);
- G = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,0))+2);
- H = _mm_setzero_pd();
- GMX_MM_TRANSPOSE2_PD(G,H);
-
- G = _mm_mul_sd(G,eps);
- H = _mm_mul_sd(H, _mm_mul_sd(eps,eps) );
- F = _mm_add_sd(F, _mm_add_sd( G , H ) );
- Y = _mm_add_sd(Y, _mm_mul_sd(F, eps));
- F = _mm_add_sd(F, _mm_add_sd(G , _mm_mul_sd(H,two)));
- vgb = _mm_mul_sd(Y, qq);
- fijGB = _mm_mul_sd(F, _mm_mul_sd(qq,gbscale));
-
- dvdatmp = _mm_mul_sd(_mm_add_sd(vgb, _mm_mul_sd(fijGB,r)) , minushalf);
-
- vgbtot = _mm_add_pd(vgbtot, vgb); /* (**) */
-
- dvdasum = _mm_add_pd(dvdasum, dvdatmp); /* (**) */
- dvdatmp = _mm_mul_sd(dvdatmp, _mm_mul_sd(isaj,isaj));
-
- GMX_MM_INCREMENT_1VALUE_PD(dvda+jnrA,dvdatmp);
-
- fscal = _mm_mul_sd( _mm_sub_sd( fscal, fijGB),rinv );
-
- /***********************************/
- /* INTERACTION SECTION ENDS HERE */
- /***********************************/
-
- /* Calculate temporary vectorial force */
- tx = _mm_mul_sd(fscal,dx);
- ty = _mm_mul_sd(fscal,dy);
- tz = _mm_mul_sd(fscal,dz);
-
- /* Increment i atom force */
- fix = _mm_add_sd(fix,tx);
- fiy = _mm_add_sd(fiy,ty);
- fiz = _mm_add_sd(fiz,tz);
-
- /* Store j forces back */
- GMX_MM_DECREMENT_1RVEC_1POINTER_PD(faction+j3A,tx,ty,tz);
- }
-
- dvdasum = _mm_mul_pd(dvdasum, _mm_mul_pd(isai,isai));
- gmx_mm_update_iforce_1atom_pd(&fix,&fiy,&fiz,faction+ii3,fshift+is3);
-
- ggid = gid[n];
-
- gmx_mm_update_1pot_pd(vctot,vc+ggid);
- gmx_mm_update_1pot_pd(vgbtot,gpol+ggid);
- gmx_mm_update_1pot_pd(dvdasum,dvda+ii);
- }
-
- *outeriter = nri;
- *inneriter = nj1;
-}
+++ /dev/null
-/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
- *
- * This file is part of Gromacs Copyright (c) 1991-2004
- * David van der Spoel, Erik Lindahl, University of Groningen.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org
- *
- * And Hey:
- * Gnomes, ROck Monsters And Chili Sauce
- */
-#ifndef _NB_KERNEL400_SSE2_DOUBLE_H_
-#define _NB_KERNEL400_SSE2_DOUBLE_H_
-
-/*! \file nb_kernel400_sse2_double.h
- * \brief SSE-optimized versions of nonbonded kernel 400
- *
- * \internal
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#if 0
-}
-#endif
-
-/*! \brief Nonbonded kernel 400 with forces, optimized for sse.
- *
- * \internal
- *
- * <b>Coulomb interaction:</b> Generalized-Born <br>
- * <b>VdW interaction:</b> No <br>
- * <b>Water optimization:</b> No <br>
- * <b>Forces calculated:</b> Yes <br>
- *
- * \note All level1 and level2 nonbonded kernels use the same
- * call sequence. Parameters are documented in nb_kernel.h
- */
-void
-nb_kernel400_sse2_double (int * nri, int iinr[], int jindex[],
- int jjnr[], int shift[], double shiftvec[],
- double fshift[], int gid[], double pos[],
- double faction[], double charge[], double * facel,
- double * krf, double * crf, double Vc[],
- int type[], int * ntype, double vdwparam[],
- double Vvdw[], double * tabscale, double VFtab[],
- double invsqrta[], double dvda[], double * gbtabscale,
- double GBtab[], int * nthreads, int * count,
- void * mtx, int * outeriter,int * inneriter,
- double * work);
-
-
-
-
-/*! \brief Nonbonded kernel 400 without forces, optimized for sse.
- *
- * \internal
- *
- * <b>Coulomb interaction:</b> Generalized-Born <br>
- * <b>VdW interaction:</b> No <br>
- * <b>Water optimization:</b> No <br>
- * <b>Forces calculated:</b> No <br>
- *
- * \note All level1 and level2 nonbonded kernels use the same
- * call sequence. Parameters are documented in nb_kernel.h
- */
-void
-nb_kernel400nf_sse2_double(int * nri, int iinr[], int jindex[],
- int jjnr[], int shift[], double shiftvec[],
- double fshift[], int gid[], double pos[],
- double faction[], double charge[], double * facel,
- double * krf, double * crf, double Vc[],
- int type[], int * ntype, double vdwparam[],
- double Vvdw[], double * tabscale, double VFtab[],
- double invsqrta[], double dvda[], double * gbtabscale,
- double GBtab[], int * nthreads, int * count,
- void * mtx, int * outeriter,int * inneriter,
- double * work);
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* _NB_KERNEL400_SSE2_DOUBLE_H_ */
+++ /dev/null
-/*
- * Copyright (c) Erik Lindahl, David van der Spoel 2003
- *
- * This file is generated automatically at compile time
- * by the program mknb in the Gromacs distribution.
- *
- * Options used when generation this file:
- * Language: c
- * Precision: double
- * Threads: no
- * Software invsqrt: yes
- * Prefetch forces: no
- * Comments: no
- */
-#ifdef HAVE_CONFIG_H
-#include<config.h>
-#endif
-#include<math.h>
-#include<vec.h>
-
-#include <emmintrin.h>
-
-#include <gmx_sse2_double.h>
-
-/* get gmx_gbdata_t */
-#include "../nb_kernel.h"
-
-
-
-void nb_kernel410_sse2_double(int * p_nri,
- int * iinr,
- int * jindex,
- int * jjnr,
- int * shift,
- double * shiftvec,
- double * fshift,
- int * gid,
- double * pos,
- double * faction,
- double * charge,
- double * p_facel,
- double * p_krf,
- double * p_crf,
- double * vc,
- int * type,
- int * p_ntype,
- double * vdwparam,
- double * vvdw,
- double * p_tabscale,
- double * VFtab,
- double * invsqrta,
- double * dvda,
- double * p_gbtabscale,
- double * GBtab,
- int * p_nthreads,
- int * count,
- void * mtx,
- int * outeriter,
- int * inneriter,
- double * work)
-{
- int nri,ntype,nthreads;
- int n,ii,is3,ii3,k,nj0,nj1,ggid;
- double shX,shY,shZ;
- int offset,nti;
- int jnrA,jnrB;
- int j3A,j3B;
- int tjA,tjB;
- gmx_gbdata_t *gbdata;
- double * gpol;
-
- __m128d iq,qq,jq,isai;
- __m128d ix,iy,iz;
- __m128d jx,jy,jz;
- __m128d dx,dy,dz;
- __m128d vctot,vvdwtot,vgbtot,dvdasum,gbfactor;
- __m128d fix,fiy,fiz,tx,ty,tz,rsq;
- __m128d rinv,isaj,isaprod;
- __m128d vcoul,fscal,gbscale,c6,c12;
- __m128d rinvsq,r,rtab;
- __m128d eps,Y,F,G,H;
- __m128d vgb,fijGB,dvdatmp;
- __m128d rinvsix,vvdw6,vvdw12;
- __m128d facel,gbtabscale,dvdaj;
- __m128i n0, nnn;
-
- const __m128d neg = _mm_set1_pd(-1.0);
- const __m128d zero = _mm_set1_pd(0.0);
- const __m128d minushalf = _mm_set1_pd(-0.5);
- const __m128d two = _mm_set1_pd(2.0);
- const __m128d six = _mm_set1_pd(6.0);
- const __m128d twelve = _mm_set1_pd(12.0);
-
- gbdata = (gmx_gbdata_t *)work;
- gpol = gbdata->gpol;
-
- nri = *p_nri;
- ntype = *p_ntype;
-
- gbfactor = _mm_set1_pd( - ((1.0/gbdata->epsilon_r) - (1.0/gbdata->gb_epsilon_solvent)));
- gbtabscale = _mm_load1_pd(p_gbtabscale);
- facel = _mm_load1_pd(p_facel);
-
- nj1 = 0;
- jnrA = jnrB = 0;
- j3A = j3B = 0;
- jx = _mm_setzero_pd();
- jy = _mm_setzero_pd();
- jz = _mm_setzero_pd();
- c6 = _mm_setzero_pd();
- c12 = _mm_setzero_pd();
-
- for(n=0;n<nri;n++)
- {
- is3 = 3*shift[n];
- shX = shiftvec[is3];
- shY = shiftvec[is3+1];
- shZ = shiftvec[is3+2];
- nj0 = jindex[n];
- nj1 = jindex[n+1];
- ii = iinr[n];
- ii3 = 3*ii;
-
- ix = _mm_set1_pd(shX+pos[ii3+0]);
- iy = _mm_set1_pd(shY+pos[ii3+1]);
- iz = _mm_set1_pd(shZ+pos[ii3+2]);
-
- iq = _mm_load1_pd(charge+ii);
- iq = _mm_mul_pd(iq,facel);
-
- isai = _mm_load1_pd(invsqrta+ii);
-
- nti = 2*ntype*type[ii];
-
- vctot = _mm_setzero_pd();
- vvdwtot = _mm_setzero_pd();
- vgbtot = _mm_setzero_pd();
- dvdasum = _mm_setzero_pd();
- fix = _mm_setzero_pd();
- fiy = _mm_setzero_pd();
- fiz = _mm_setzero_pd();
-
- for(k=nj0;k<nj1-1; k+=2)
- {
- jnrA = jjnr[k];
- jnrB = jjnr[k+1];
-
- j3A = jnrA * 3;
- j3B = jnrB * 3;
-
- GMX_MM_LOAD_1RVEC_2POINTERS_PD(pos+j3A,pos+j3B,jx,jy,jz);
-
- dx = _mm_sub_pd(ix,jx);
- dy = _mm_sub_pd(iy,jy);
- dz = _mm_sub_pd(iz,jz);
-
- rsq = gmx_mm_calc_rsq_pd(dx,dy,dz);
-
- rinv = gmx_mm_invsqrt_pd(rsq);
- rinvsq = _mm_mul_pd(rinv,rinv);
-
- /***********************************/
- /* INTERACTION SECTION STARTS HERE */
- /***********************************/
- GMX_MM_LOAD_2VALUES_PD(charge+jnrA,charge+jnrB,jq);
- GMX_MM_LOAD_2VALUES_PD(invsqrta+jnrA,invsqrta+jnrB,isaj);
-
- /* Lennard-Jones */
- tjA = nti+2*type[jnrA];
- tjB = nti+2*type[jnrB];
-
- GMX_MM_LOAD_2PAIRS_PD(vdwparam+tjA,vdwparam+tjB,c6,c12);
-
- isaprod = _mm_mul_pd(isai,isaj);
- qq = _mm_mul_pd(iq,jq);
- vcoul = _mm_mul_pd(qq,rinv);
- fscal = _mm_mul_pd(vcoul,rinv);
- vctot = _mm_add_pd(vctot,vcoul);
-
- /* Polarization interaction */
- qq = _mm_mul_pd(qq,_mm_mul_pd(isaprod,gbfactor));
- gbscale = _mm_mul_pd(isaprod,gbtabscale);
-
- /* Calculate GB table index */
- r = _mm_mul_pd(rsq,rinv);
- rtab = _mm_mul_pd(r,gbscale);
-
- n0 = _mm_cvttpd_epi32(rtab);
- eps = _mm_sub_pd(rtab,_mm_cvtepi32_pd(n0));
- nnn = _mm_slli_epi32(n0,2);
-
- /* the tables are 16-byte aligned, so we can use _mm_load_pd */
- Y = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,0)));
- F = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,1)));
- GMX_MM_TRANSPOSE2_PD(Y,F);
- G = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,0))+2);
- H = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,1))+2);
- GMX_MM_TRANSPOSE2_PD(G,H);
-
- G = _mm_mul_pd(G,eps);
- H = _mm_mul_pd(H, _mm_mul_pd(eps,eps) );
- F = _mm_add_pd(F, _mm_add_pd( G , H ) );
- Y = _mm_add_pd(Y, _mm_mul_pd(F, eps));
- F = _mm_add_pd(F, _mm_add_pd(G , _mm_mul_pd(H,two)));
- vgb = _mm_mul_pd(Y, qq);
- fijGB = _mm_mul_pd(F, _mm_mul_pd(qq,gbscale));
-
- dvdatmp = _mm_mul_pd(_mm_add_pd(vgb, _mm_mul_pd(fijGB,r)) , minushalf);
-
- vgbtot = _mm_add_pd(vgbtot, vgb);
-
- dvdasum = _mm_add_pd(dvdasum, dvdatmp);
- dvdatmp = _mm_mul_pd(dvdatmp, _mm_mul_pd(isaj,isaj));
-
- GMX_MM_INCREMENT_2VALUES_PD(dvda+jnrA,dvda+jnrB,dvdatmp);
-
- rinvsix = _mm_mul_pd(rinvsq,rinvsq);
- rinvsix = _mm_mul_pd(rinvsix,rinvsq);
-
- vvdw6 = _mm_mul_pd(c6,rinvsix);
- vvdw12 = _mm_mul_pd(c12, _mm_mul_pd(rinvsix,rinvsix));
- vvdwtot = _mm_add_pd(vvdwtot,_mm_sub_pd(vvdw12,vvdw6));
-
- fscal = _mm_sub_pd(_mm_mul_pd(rinvsq,
- _mm_sub_pd(_mm_mul_pd(twelve,vvdw12),
- _mm_mul_pd(six,vvdw6))),
- _mm_mul_pd( _mm_sub_pd( fijGB,fscal),rinv ));
-
- /***********************************/
- /* INTERACTION SECTION ENDS HERE */
- /***********************************/
-
- /* Calculate temporary vectorial force */
- tx = _mm_mul_pd(fscal,dx);
- ty = _mm_mul_pd(fscal,dy);
- tz = _mm_mul_pd(fscal,dz);
-
- /* Increment i atom force */
- fix = _mm_add_pd(fix,tx);
- fiy = _mm_add_pd(fiy,ty);
- fiz = _mm_add_pd(fiz,tz);
-
- /* Store j forces back */
- GMX_MM_DECREMENT_1RVEC_2POINTERS_PD(faction+j3A,faction+j3B,tx,ty,tz);
- }
-
- /* In double precision, offset can only be either 0 or 1 */
- if(k<nj1)
- {
- jnrA = jjnr[k];
-
- j3A = jnrA * 3;
-
- GMX_MM_LOAD_1RVEC_1POINTER_PD(pos+j3A,jx,jy,jz);
-
- dx = _mm_sub_sd(ix,jx);
- dy = _mm_sub_sd(iy,jy);
- dz = _mm_sub_sd(iz,jz);
-
- rsq = gmx_mm_calc_rsq_pd(dx,dy,dz);
-
- rinv = gmx_mm_invsqrt_pd(rsq);
- rinvsq = _mm_mul_sd(rinv,rinv);
-
- /* These reason for zeroing these variables here is for fixing bug 585
- * What happens is that __m128d _mm_add_sd(a,b) gives back r0=a[0]+b[0],
- * and r1=0, but it should be r1=a[1].
- * This might be a compiler issue (tested with gcc-4.1.3 and -O3).
- * To work around it, we zero these variables and use _mm_add_pd (**) instead
- * Note that the only variables that get affected are the energies since
- * the total sum needs to be correct
- */
- vgb = _mm_setzero_pd();
- vcoul = _mm_setzero_pd();
- dvdatmp = _mm_setzero_pd();
- vvdw6 = _mm_setzero_pd();
- vvdw12 = _mm_setzero_pd();
-
- /***********************************/
- /* INTERACTION SECTION STARTS HERE */
- /***********************************/
- GMX_MM_LOAD_1VALUE_PD(charge+jnrA,jq);
- GMX_MM_LOAD_1VALUE_PD(invsqrta+jnrA,isaj);
-
- /* Lennard-Jones */
- tjA = nti+2*type[jnrA];
-
- GMX_MM_LOAD_1PAIR_PD(vdwparam+tjA,c6,c12);
-
- isaprod = _mm_mul_sd(isai,isaj);
- qq = _mm_mul_sd(jq,iq);
- vcoul = _mm_mul_sd(qq,rinv);
- fscal = _mm_mul_sd(vcoul,rinv);
- vctot = _mm_add_pd(vctot,vcoul); /* (**) */
-
- /* Polarization interaction */
- qq = _mm_mul_sd(qq,_mm_mul_sd(isaprod,gbfactor));
- gbscale = _mm_mul_sd(isaprod,gbtabscale);
-
- /* Calculate GB table index */
- r = _mm_mul_sd(rsq,rinv);
- rtab = _mm_mul_sd(r,gbscale);
-
- n0 = _mm_cvttpd_epi32(rtab);
- eps = _mm_sub_sd(rtab,_mm_cvtepi32_pd(n0));
- nnn = _mm_slli_epi32(n0,2);
-
- /* the tables are 16-byte aligned, so we can use _mm_load_pd */
- Y = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,0)));
- F = _mm_setzero_pd();
- GMX_MM_TRANSPOSE2_PD(Y,F);
- G = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,0))+2);
- H = _mm_setzero_pd();
- GMX_MM_TRANSPOSE2_PD(G,H);
-
- G = _mm_mul_sd(G,eps);
- H = _mm_mul_sd(H, _mm_mul_sd(eps,eps) );
- F = _mm_add_sd(F, _mm_add_sd( G , H ) );
- Y = _mm_add_sd(Y, _mm_mul_sd(F, eps));
- F = _mm_add_sd(F, _mm_add_sd(G , _mm_mul_sd(H,two)));
- vgb = _mm_mul_sd(Y, qq);
- fijGB = _mm_mul_sd(F, _mm_mul_sd(qq,gbscale));
-
- dvdatmp = _mm_mul_sd(_mm_add_sd(vgb, _mm_mul_sd(fijGB,r)) , minushalf);
-
- vgbtot = _mm_add_pd(vgbtot, vgb); /* (**) */
-
- dvdasum = _mm_add_pd(dvdasum, dvdatmp); /* (**) */
- dvdatmp = _mm_mul_sd(dvdatmp, _mm_mul_sd(isaj,isaj));
-
- GMX_MM_INCREMENT_1VALUE_PD(dvda+jnrA,dvdatmp);
-
- rinvsix = _mm_mul_sd(rinvsq,rinvsq);
- rinvsix = _mm_mul_sd(rinvsix,rinvsq);
-
- vvdw6 = _mm_mul_sd(c6,rinvsix);
- vvdw12 = _mm_mul_sd(c12, _mm_mul_sd(rinvsix,rinvsix));
- vvdwtot = _mm_add_pd(vvdwtot,_mm_sub_sd(vvdw12,vvdw6)); /* (**) */
-
- fscal = _mm_sub_sd(_mm_mul_sd(rinvsq,
- _mm_sub_sd(_mm_mul_sd(twelve,vvdw12),
- _mm_mul_sd(six,vvdw6))),
- _mm_mul_sd( _mm_sub_sd( fijGB,fscal),rinv ));
-
- /***********************************/
- /* INTERACTION SECTION ENDS HERE */
- /***********************************/
-
- /* Calculate temporary vectorial force */
- tx = _mm_mul_sd(fscal,dx);
- ty = _mm_mul_sd(fscal,dy);
- tz = _mm_mul_sd(fscal,dz);
-
- /* Increment i atom force */
- fix = _mm_add_sd(fix,tx);
- fiy = _mm_add_sd(fiy,ty);
- fiz = _mm_add_sd(fiz,tz);
-
- /* Store j forces back */
- GMX_MM_DECREMENT_1RVEC_1POINTER_PD(faction+j3A,tx,ty,tz);
- }
-
- dvdasum = _mm_mul_pd(dvdasum, _mm_mul_pd(isai,isai));
- gmx_mm_update_iforce_1atom_pd(&fix,&fiy,&fiz,faction+ii3,fshift+is3);
-
- ggid = gid[n];
-
- gmx_mm_update_1pot_pd(vctot,vc+ggid);
- gmx_mm_update_1pot_pd(vgbtot,gpol+ggid);
- gmx_mm_update_1pot_pd(dvdasum,dvda+ii);
- gmx_mm_update_1pot_pd(vvdwtot,vvdw+ggid);
-
- }
-
- *outeriter = nri;
- *inneriter = nj1;
-}
+++ /dev/null
-/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
- *
- * This file is part of Gromacs Copyright (c) 1991-2004
- * David van der Spoel, Erik Lindahl, University of Groningen.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org
- *
- * And Hey:
- * Gnomes, ROck Monsters And Chili Sauce
- */
-#ifndef _NB_KERNEL410_SSE2_DOUBLE_H_
-#define _NB_KERNEL410_SSE2_DOUBLE_H_
-
-/*! \file nb_kernel410_sse2_double.h
- * \brief SSE-optimized versions of nonbonded kernel 410
- *
- * \internal
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#if 0
-}
-#endif
-
-/*! \brief Nonbonded kernel 410 with forces, optimized for sse.
- *
- * \internal
- *
- * <b>Coulomb interaction:</b> Generalized-Born <br>
- * <b>VdW interaction:</b> Lennard-Jones <br>
- * <b>Water optimization:</b> No <br>
- * <b>Forces calculated:</b> Yes <br>
- *
- * \note All level1 and level2 nonbonded kernels use the same
- * call sequence. Parameters are documented in nb_kernel.h
- */
-void
-nb_kernel410_sse2_double (int * nri, int iinr[], int jindex[],
- int jjnr[], int shift[], double shiftvec[],
- double fshift[], int gid[], double pos[],
- double faction[], double charge[], double * facel,
- double * krf, double * crf, double Vc[],
- int type[], int * ntype, double vdwparam[],
- double Vvdw[], double * tabscale, double VFtab[],
- double invsqrta[], double dvda[], double * gbtabscale,
- double GBtab[], int * nthreads, int * count,
- void * mtx, int * outeriter,int * inneriter,
- double * work);
-
-
-
-/*! \brief Nonbonded kernel 410 without forces, optimized for sse.
- *
- * \internal
- *
- * <b>Coulomb interaction:</b> Generalized-Born <br>
- * <b>VdW interaction:</b> Lennard-Jones <br>
- * <b>Water optimization:</b> No <br>
- * <b>Forces calculated:</b> No <br>
- *
- * \note All level1 and level2 nonbonded kernels use the same
- * call sequence. Parameters are documented in nb_kernel.h
- */
-void
-nb_kernel410nf_sse2_double(int * nri, int iinr[], int jindex[],
- int jjnr[], int shift[], double shiftvec[],
- double fshift[], int gid[], double pos[],
- double faction[], double charge[], double * facel,
- double * krf, double * crf, double Vc[],
- int type[], int * ntype, double vdwparam[],
- double Vvdw[], double * tabscale, double VFtab[],
- double invsqrta[], double dvda[], double * gbtabscale,
- double GBtab[], int * nthreads, int * count,
- void * mtx, int * outeriter,int * inneriter,
- double * work);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-
-#endif /* _NB_KERNEL410_SSE2_DOUBLE_H_ */
+++ /dev/null
-/*
- * Copyright (c) Erik Lindahl, David van der Spoel 2003
- *
- * This file is generated automatically at compile time
- * by the program mknb in the Gromacs distribution.
- *
- * Options used when generation this file:
- * Language: c
- * Precision: double
- * Threads: no
- * Software invsqrt: yes
- * Prefetch forces: no
- * Comments: no
- */
-#ifdef HAVE_CONFIG_H
-#include<config.h>
-#endif
-#include<math.h>
-#include<vec.h>
-
-#include <emmintrin.h>
-
-#include <gmx_sse2_double.h>
-
-/* get gmx_gbdata_t */
-#include "../nb_kernel.h"
-
-
-void nb_kernel430_sse2_double(int * p_nri,
- int * iinr,
- int * jindex,
- int * jjnr,
- int * shift,
- double * shiftvec,
- double * fshift,
- int * gid,
- double * pos,
- double * faction,
- double * charge,
- double * p_facel,
- double * p_krf,
- double * p_crf,
- double * vc,
- int * type,
- int * p_ntype,
- double * vdwparam,
- double * vvdw,
- double * p_tabscale,
- double * VFtab,
- double * invsqrta,
- double * dvda,
- double * p_gbtabscale,
- double * GBtab,
- int * p_nthreads,
- int * count,
- void * mtx,
- int * outeriter,
- int * inneriter,
- double * work)
-{
- int nri,ntype,nthreads;
- int n,ii,is3,ii3,k,nj0,nj1,ggid;
- double shX,shY,shZ;
- int offset,nti;
- int jnrA,jnrB;
- int j3A,j3B;
- int tjA,tjB;
- gmx_gbdata_t *gbdata;
- double * gpol;
-
- __m128d iq,qq,jq,isai;
- __m128d ix,iy,iz;
- __m128d jx,jy,jz;
- __m128d dx,dy,dz;
- __m128d vctot,vvdwtot,vgbtot,dvdasum,gbfactor;
- __m128d fix,fiy,fiz,tx,ty,tz,rsq;
- __m128d rinv,isaj,isaprod;
- __m128d vcoul,fscal,gbscale,c6,c12;
- __m128d rinvsq,r,rtab;
- __m128d eps,Y,F,G,H;
- __m128d VV,FF,Fp;
- __m128d vgb,fijGB,dvdatmp;
- __m128d rinvsix,vvdw6,vvdw12,vvdwtmp;
- __m128d facel,gbtabscale,dvdaj;
- __m128d fijD,fijR;
- __m128d xmm1,tabscale,eps2;
- __m128i n0, nnn;
-
-
- const __m128d neg = _mm_set1_pd(-1.0);
- const __m128d zero = _mm_set1_pd(0.0);
- const __m128d minushalf = _mm_set1_pd(-0.5);
- const __m128d two = _mm_set1_pd(2.0);
-
- gbdata = (gmx_gbdata_t *)work;
- gpol = gbdata->gpol;
-
- nri = *p_nri;
- ntype = *p_ntype;
-
- gbfactor = _mm_set1_pd( - ((1.0/gbdata->epsilon_r) - (1.0/gbdata->gb_epsilon_solvent)));
- gbtabscale = _mm_load1_pd(p_gbtabscale);
- facel = _mm_load1_pd(p_facel);
- tabscale = _mm_load1_pd(p_tabscale);
-
- nj1 = 0;
- jnrA = jnrB = 0;
- j3A = j3B = 0;
- jx = _mm_setzero_pd();
- jy = _mm_setzero_pd();
- jz = _mm_setzero_pd();
- c6 = _mm_setzero_pd();
- c12 = _mm_setzero_pd();
-
- for(n=0;n<nri;n++)
- {
- is3 = 3*shift[n];
- shX = shiftvec[is3];
- shY = shiftvec[is3+1];
- shZ = shiftvec[is3+2];
- nj0 = jindex[n];
- nj1 = jindex[n+1];
- ii = iinr[n];
- ii3 = 3*ii;
-
- ix = _mm_set1_pd(shX+pos[ii3+0]);
- iy = _mm_set1_pd(shY+pos[ii3+1]);
- iz = _mm_set1_pd(shZ+pos[ii3+2]);
-
- iq = _mm_load1_pd(charge+ii);
- iq = _mm_mul_pd(iq,facel);
-
- isai = _mm_load1_pd(invsqrta+ii);
-
- nti = 2*ntype*type[ii];
-
- vctot = _mm_setzero_pd();
- vvdwtot = _mm_setzero_pd();
- vgbtot = _mm_setzero_pd();
- dvdasum = _mm_setzero_pd();
- fix = _mm_setzero_pd();
- fiy = _mm_setzero_pd();
- fiz = _mm_setzero_pd();
-
- for(k=nj0;k<nj1-1; k+=2)
- {
- jnrA = jjnr[k];
- jnrB = jjnr[k+1];
-
- j3A = jnrA * 3;
- j3B = jnrB * 3;
-
- GMX_MM_LOAD_1RVEC_2POINTERS_PD(pos+j3A,pos+j3B,jx,jy,jz);
-
- dx = _mm_sub_pd(ix,jx);
- dy = _mm_sub_pd(iy,jy);
- dz = _mm_sub_pd(iz,jz);
-
- rsq = gmx_mm_calc_rsq_pd(dx,dy,dz);
-
- rinv = gmx_mm_invsqrt_pd(rsq);
- rinvsq = _mm_mul_pd(rinv,rinv);
-
- /***********************************/
- /* INTERACTION SECTION STARTS HERE */
- /***********************************/
- GMX_MM_LOAD_2VALUES_PD(charge+jnrA,charge+jnrB,jq);
- GMX_MM_LOAD_2VALUES_PD(invsqrta+jnrA,invsqrta+jnrB,isaj);
-
- /* Lennard-Jones */
- tjA = nti+2*type[jnrA];
- tjB = nti+2*type[jnrB];
-
- GMX_MM_LOAD_2PAIRS_PD(vdwparam+tjA,vdwparam+tjB,c6,c12);
-
- isaprod = _mm_mul_pd(isai,isaj);
- qq = _mm_mul_pd(iq,jq);
- vcoul = _mm_mul_pd(qq,rinv);
- fscal = _mm_mul_pd(vcoul,rinv);
- vctot = _mm_add_pd(vctot,vcoul);
-
- /* Polarization interaction */
- qq = _mm_mul_pd(qq,_mm_mul_pd(isaprod,gbfactor));
- gbscale = _mm_mul_pd(isaprod,gbtabscale);
-
- /* Calculate GB table index */
- r = _mm_mul_pd(rsq,rinv);
- rtab = _mm_mul_pd(r,gbscale);
-
- n0 = _mm_cvttpd_epi32(rtab);
- eps = _mm_sub_pd(rtab,_mm_cvtepi32_pd(n0));
- nnn = _mm_slli_epi32(n0,2);
-
- /* the tables are 16-byte aligned, so we can use _mm_load_pd */
- Y = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,0)));
- F = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,1)));
- GMX_MM_TRANSPOSE2_PD(Y,F);
- G = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,0))+2);
- H = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,1))+2);
- GMX_MM_TRANSPOSE2_PD(G,H);
-
- G = _mm_mul_pd(G,eps);
- H = _mm_mul_pd(H, _mm_mul_pd(eps,eps) );
- F = _mm_add_pd(F, _mm_add_pd( G , H ) );
- Y = _mm_add_pd(Y, _mm_mul_pd(F, eps));
- F = _mm_add_pd(F, _mm_add_pd(G , _mm_mul_pd(H,two)));
- vgb = _mm_mul_pd(Y, qq);
- fijGB = _mm_mul_pd(F, _mm_mul_pd(qq,gbscale));
-
- dvdatmp = _mm_mul_pd(_mm_add_pd(vgb, _mm_mul_pd(fijGB,r)) , minushalf);
-
- vgbtot = _mm_add_pd(vgbtot, vgb);
-
- dvdasum = _mm_add_pd(dvdasum, dvdatmp);
- dvdatmp = _mm_mul_pd(dvdatmp, _mm_mul_pd(isaj,isaj));
-
- GMX_MM_INCREMENT_2VALUES_PD(dvda+jnrA,dvda+jnrB,dvdatmp);
-
- /* Calculate VDW table index */
- rtab = _mm_mul_pd(r,tabscale);
- n0 = _mm_cvttpd_epi32(rtab);
- eps = _mm_sub_pd(rtab,_mm_cvtepi32_pd(n0));
- eps2 = _mm_mul_pd(eps,eps);
- nnn = _mm_slli_epi32(n0,3);
-
- /* Dispersion */
- Y = _mm_load_pd(VFtab+(gmx_mm_extract_epi32(nnn,0)));
- F = _mm_load_pd(VFtab+(gmx_mm_extract_epi32(nnn,1)));
- GMX_MM_TRANSPOSE2_PD(Y,F);
- G = _mm_load_pd(VFtab+(gmx_mm_extract_epi32(nnn,0))+2);
- H = _mm_load_pd(VFtab+(gmx_mm_extract_epi32(nnn,1))+2);
- GMX_MM_TRANSPOSE2_PD(G,H);
-
- G = _mm_mul_pd(G,eps);
- H = _mm_mul_pd(H,eps2);
- Fp = _mm_add_pd(F,G);
- Fp = _mm_add_pd(Fp,H);
- VV = _mm_mul_pd(Fp,eps);
- VV = _mm_add_pd(Y,VV);
- xmm1 = _mm_mul_pd(two,H);
- FF = _mm_add_pd(Fp,G);
- FF = _mm_add_pd(FF,xmm1);
-
- vvdw6 = _mm_mul_pd(c6,VV);
- fijD = _mm_mul_pd(c6,FF);
-
- /* Dispersion */
- Y = _mm_load_pd(VFtab+(gmx_mm_extract_epi32(nnn,0))+4);
- F = _mm_load_pd(VFtab+(gmx_mm_extract_epi32(nnn,1))+4);
- GMX_MM_TRANSPOSE2_PD(Y,F);
- G = _mm_load_pd(VFtab+(gmx_mm_extract_epi32(nnn,0))+6);
- H = _mm_load_pd(VFtab+(gmx_mm_extract_epi32(nnn,1))+6);
- GMX_MM_TRANSPOSE2_PD(G,H);
-
- G = _mm_mul_pd(G,eps);
- H = _mm_mul_pd(H,eps2);
- Fp = _mm_add_pd(F,G);
- Fp = _mm_add_pd(Fp,H);
- VV = _mm_mul_pd(Fp,eps);
- VV = _mm_add_pd(Y,VV);
- xmm1 = _mm_mul_pd(two,H);
- FF = _mm_add_pd(Fp,G);
- FF = _mm_add_pd(FF,xmm1);
-
- vvdw12 = _mm_mul_pd(c12,VV);
- fijR = _mm_mul_pd(c12,FF);
-
- vvdwtmp = _mm_add_pd(vvdw12,vvdw6);
- vvdwtot = _mm_add_pd(vvdwtot,vvdwtmp);
-
- xmm1 = _mm_add_pd(fijD,fijR);
- xmm1 = _mm_mul_pd(xmm1,tabscale);
- xmm1 = _mm_add_pd(xmm1,fijGB);
- xmm1 = _mm_sub_pd(xmm1,fscal);
- fscal = _mm_mul_pd(xmm1,neg);
- fscal = _mm_mul_pd(fscal,rinv);
-
- /***********************************/
- /* INTERACTION SECTION ENDS HERE */
- /***********************************/
-
- /* Calculate temporary vectorial force */
- tx = _mm_mul_pd(fscal,dx);
- ty = _mm_mul_pd(fscal,dy);
- tz = _mm_mul_pd(fscal,dz);
-
- /* Increment i atom force */
- fix = _mm_add_pd(fix,tx);
- fiy = _mm_add_pd(fiy,ty);
- fiz = _mm_add_pd(fiz,tz);
-
- /* Store j forces back */
- GMX_MM_DECREMENT_1RVEC_2POINTERS_PD(faction+j3A,faction+j3B,tx,ty,tz);
- }
-
- /* In double precision, offset can only be either 0 or 1 */
- if(k<nj1)
- {
- jnrA = jjnr[k];
- j3A = jnrA * 3;
-
- GMX_MM_LOAD_1RVEC_1POINTER_PD(pos+j3A,jx,jy,jz);
-
- dx = _mm_sub_sd(ix,jx);
- dy = _mm_sub_sd(iy,jy);
- dz = _mm_sub_sd(iz,jz);
-
- rsq = gmx_mm_calc_rsq_pd(dx,dy,dz);
-
- rinv = gmx_mm_invsqrt_pd(rsq);
- rinvsq = _mm_mul_sd(rinv,rinv);
-
- /* These reason for zeroing these variables here is for fixing bug 585
- * What happens is that __m128d _mm_add_sd(a,b) gives back r0=a[0]+b[0],
- * and r1=0, but it should be r1=a[1].
- * This might be a compiler issue (tested with gcc-4.1.3 and -O3).
- * To work around it, we zero these variables and use _mm_add_pd (**) instead
- * Note that the only variables that get affected are the energies since
- * the total sum needs to be correct
- */
- vgb = _mm_setzero_pd();
- vcoul = _mm_setzero_pd();
- dvdatmp = _mm_setzero_pd();
- vvdw6 = _mm_setzero_pd();
- vvdw12 = _mm_setzero_pd();
-
- /***********************************/
- /* INTERACTION SECTION STARTS HERE */
- /***********************************/
- GMX_MM_LOAD_1VALUE_PD(charge+jnrA,jq);
- GMX_MM_LOAD_1VALUE_PD(invsqrta+jnrA,isaj);
-
- /* Lennard-Jones */
- tjA = nti+2*type[jnrA];
-
- GMX_MM_LOAD_1PAIR_PD(vdwparam+tjA,c6,c12);
-
- isaprod = _mm_mul_sd(isai,isaj);
- qq = _mm_mul_sd(jq,iq);
- vcoul = _mm_mul_sd(qq,rinv);
- fscal = _mm_mul_sd(vcoul,rinv);
- vctot = _mm_add_pd(vctot,vcoul); /* (**) */
-
- /* Polarization interaction */
- qq = _mm_mul_sd(qq,_mm_mul_sd(isaprod,gbfactor));
- gbscale = _mm_mul_sd(isaprod,gbtabscale);
-
- /* Calculate GB table index */
- r = _mm_mul_sd(rsq,rinv);
- rtab = _mm_mul_sd(r,gbscale);
-
- n0 = _mm_cvttpd_epi32(rtab);
- eps = _mm_sub_sd(rtab,_mm_cvtepi32_pd(n0));
- nnn = _mm_slli_epi32(n0,2);
-
- /* the tables are 16-byte aligned, so we can use _mm_load_pd */
- Y = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,0)));
- F = _mm_setzero_pd();
- GMX_MM_TRANSPOSE2_PD(Y,F);
- G = _mm_load_pd(GBtab+(gmx_mm_extract_epi32(nnn,0))+2);
- H = _mm_setzero_pd();
- GMX_MM_TRANSPOSE2_PD(G,H);
-
- G = _mm_mul_sd(G,eps);
- H = _mm_mul_sd(H, _mm_mul_sd(eps,eps) );
- F = _mm_add_sd(F, _mm_add_sd( G , H ) );
- Y = _mm_add_sd(Y, _mm_mul_sd(F, eps));
- F = _mm_add_sd(F, _mm_add_sd(G , _mm_mul_sd(H,two)));
- vgb = _mm_mul_sd(Y, qq);
- fijGB = _mm_mul_sd(F, _mm_mul_sd(qq,gbscale));
-
- dvdatmp = _mm_mul_sd(_mm_add_sd(vgb, _mm_mul_sd(fijGB,r)) , minushalf);
-
- vgbtot = _mm_add_pd(vgbtot, vgb); /* (**) */
-
- dvdasum = _mm_add_pd(dvdasum, dvdatmp); /* (**) */
- dvdatmp = _mm_mul_sd(dvdatmp, _mm_mul_sd(isaj,isaj));
-
- GMX_MM_INCREMENT_1VALUE_PD(dvda+jnrA,dvdatmp);
-
- /* Calculate VDW table index */
- rtab = _mm_mul_sd(r,tabscale);
- n0 = _mm_cvttpd_epi32(rtab);
- eps = _mm_sub_sd(rtab,_mm_cvtepi32_pd(n0));
- eps2 = _mm_mul_sd(eps,eps);
- nnn = _mm_slli_epi32(n0,3);
-
- /* Dispersion */
- Y = _mm_load_pd(VFtab+(gmx_mm_extract_epi32(nnn,0)));
- F = _mm_setzero_pd();
- GMX_MM_TRANSPOSE2_PD(Y,F);
- G = _mm_load_pd(VFtab+(gmx_mm_extract_epi32(nnn,0))+2);
- H = _mm_setzero_pd();
- GMX_MM_TRANSPOSE2_PD(G,H);
-
- G = _mm_mul_sd(G,eps);
- H = _mm_mul_sd(H,eps2);
- Fp = _mm_add_sd(F,G);
- Fp = _mm_add_sd(Fp,H);
- VV = _mm_mul_sd(Fp,eps);
- VV = _mm_add_sd(Y,VV);
- xmm1 = _mm_mul_sd(two,H);
- FF = _mm_add_sd(Fp,G);
- FF = _mm_add_sd(FF,xmm1);
-
- vvdw6 = _mm_mul_sd(c6,VV);
- fijD = _mm_mul_sd(c6,FF);
-
- /* Dispersion */
- Y = _mm_load_pd(VFtab+(gmx_mm_extract_epi32(nnn,0))+4);
- F = _mm_setzero_pd();
- GMX_MM_TRANSPOSE2_PD(Y,F);
- G = _mm_load_pd(VFtab+(gmx_mm_extract_epi32(nnn,0))+6);
- H = _mm_setzero_pd();
- GMX_MM_TRANSPOSE2_PD(G,H);
-
- G = _mm_mul_sd(G,eps);
- H = _mm_mul_sd(H,eps2);
- Fp = _mm_add_sd(F,G);
- Fp = _mm_add_sd(Fp,H);
- VV = _mm_mul_sd(Fp,eps);
- VV = _mm_add_sd(Y,VV);
- xmm1 = _mm_mul_sd(two,H);
- FF = _mm_add_sd(Fp,G);
- FF = _mm_add_sd(FF,xmm1);
-
- vvdw12 = _mm_mul_sd(c12,VV);
- fijR = _mm_mul_sd(c12,FF);
-
- vvdwtmp = _mm_add_sd(vvdw12,vvdw6);
- vvdwtot = _mm_add_pd(vvdwtot,vvdwtmp); /* (**) */
-
- xmm1 = _mm_add_sd(fijD,fijR);
- xmm1 = _mm_mul_sd(xmm1,tabscale);
- xmm1 = _mm_add_sd(xmm1,fijGB);
- xmm1 = _mm_sub_sd(xmm1,fscal);
- fscal = _mm_mul_sd(xmm1,neg);
- fscal = _mm_mul_sd(fscal,rinv);
-
- /***********************************/
- /* INTERACTION SECTION ENDS HERE */
- /***********************************/
-
- /* Calculate temporary vectorial force */
- tx = _mm_mul_sd(fscal,dx);
- ty = _mm_mul_sd(fscal,dy);
- tz = _mm_mul_sd(fscal,dz);
-
- /* Increment i atom force */
- fix = _mm_add_sd(fix,tx);
- fiy = _mm_add_sd(fiy,ty);
- fiz = _mm_add_sd(fiz,tz);
-
- /* Store j forces back */
- GMX_MM_DECREMENT_1RVEC_1POINTER_PD(faction+j3A,tx,ty,tz);
- }
-
- dvdasum = _mm_mul_pd(dvdasum, _mm_mul_pd(isai,isai));
- gmx_mm_update_iforce_1atom_pd(&fix,&fiy,&fiz,faction+ii3,fshift+is3);
-
- ggid = gid[n];
-
- gmx_mm_update_1pot_pd(vctot,vc+ggid);
- gmx_mm_update_1pot_pd(vgbtot,gpol+ggid);
- gmx_mm_update_1pot_pd(dvdasum,dvda+ii);
- gmx_mm_update_1pot_pd(vvdwtot,vvdw+ggid);
-
- }
-
- *outeriter = nri;
- *inneriter = nj1;
-}
-
+++ /dev/null
-/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
- *
- * This file is part of Gromacs Copyright (c) 1991-2004
- * David van der Spoel, Erik Lindahl, University of Groningen.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org
- *
- * And Hey:
- * Gnomes, ROck Monsters And Chili Sauce
- */
-#ifndef _NB_KERNEL430_SSE2_DOUBLE_H_
-#define _NB_KERNEL430_SSE2_DOUBLE_H_
-
-/*! \file nb_kernel430_sse2_double.h
- * \brief SSE-intrinsics optimized versions of nonbonded kernel 430
- *
- * \internal
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#if 0
-}
-#endif
-
-/*! \brief Nonbonded kernel 430 with forces, optimized for sse.
- *
- * \internal
- *
- * <b>Coulomb interaction:</b> Generalized-Born <br>
- * <b>VdW interaction:</b> Tabulated <br>
- * <b>Water optimization:</b> No <br>
- * <b>Forces calculated:</b> Yes <br>
- *
- * \note All level1 and level2 nonbonded kernels use the same
- * call sequence. Parameters are documented in nb_kernel.h
- */
-void
-nb_kernel430_sse2_double (int * nri, int iinr[], int jindex[],
- int jjnr[], int shift[], double shiftvec[],
- double fshift[], int gid[], double pos[],
- double faction[], double charge[], double * facel,
- double * krf, double * crf, double Vc[],
- int type[], int * ntype, double vdwparam[],
- double Vvdw[], double * tabscale, double VFtab[],
- double invsqrta[], double dvda[], double * gbtabscale,
- double GBtab[], int * nthreads, int * count,
- void * mtx, int * outeriter,int * inneriter,
- double * work);
-
-
-
-
-/*! \brief Nonbonded kernel 430 without forces, optimized for sse.
- *
- * \internal
- *
- * <b>Coulomb interaction:</b> Generalized-Born <br>
- * <b>VdW interaction:</b> Tabulated <br>
- * <b>Water optimization:</b> No <br>
- * <b>Forces calculated:</b> No <br>
- *
- * \note All level1 and level2 nonbonded kernels use the same
- * call sequence. Parameters are documented in nb_kernel.h
- */
-void
-nb_kernel430nf_sse2_double(int * nri, int iinr[], int jindex[],
- int jjnr[], int shift[], double shiftvec[],
- double fshift[], int gid[], double pos[],
- double faction[], double charge[], double * facel,
- double * krf, double * crf, double Vc[],
- int type[], int * ntype, double vdwparam[],
- double Vvdw[], double * tabscale, double VFtab[],
- double invsqrta[], double dvda[], double * gbtabscale,
- double GBtab[], int * nthreads, int * count,
- void * mtx, int * outeriter,int * inneriter,
- double * work);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-
-#endif /* _NB_KERNEL430_SSE2_DOUBLE_H_ */
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwCSTab_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: CubicSplineTable
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCSTab_VdwCSTab_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec_vdw->scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 73 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 73 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 9 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_VF,outeriter*9 + inneriter*73);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwCSTab_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: CubicSplineTable
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCSTab_VdwCSTab_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec_vdw->scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 61 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 61 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_F,outeriter*7 + inneriter*61);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwCSTab_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCSTab_VdwCSTab_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 162 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 162 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_VF,outeriter*20 + inneriter*162);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwCSTab_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCSTab_VdwCSTab_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 142 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 142 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_F,outeriter*18 + inneriter*142);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwCSTab_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCSTab_VdwCSTab_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r01,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq01,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq01,FF),_mm_mul_pd(vftabscale,rinv01)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r02,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq02,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq02,FF),_mm_mul_pd(vftabscale,rinv02)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq11,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq12,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq21,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq22,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 417 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r01,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq01,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq01,FF),_mm_mul_pd(vftabscale,rinv01)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r02,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq02,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq02,FF),_mm_mul_pd(vftabscale,rinv02)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq11,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq12,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq21,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq22,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 417 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_VF,outeriter*20 + inneriter*417);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwCSTab_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCSTab_VdwCSTab_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r01,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq01,FF),_mm_mul_pd(vftabscale,rinv01)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r02,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq02,FF),_mm_mul_pd(vftabscale,rinv02)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 373 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r01,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq01,FF),_mm_mul_pd(vftabscale,rinv01)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r02,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq02,FF),_mm_mul_pd(vftabscale,rinv02)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 373 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_F,outeriter*18 + inneriter*373);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwCSTab_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCSTab_VdwCSTab_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r30,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq30,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq30,FF),_mm_mul_pd(vftabscale,rinv30)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 188 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r30,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq30,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq30,FF),_mm_mul_pd(vftabscale,rinv30)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 188 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_VF,outeriter*26 + inneriter*188);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwCSTab_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCSTab_VdwCSTab_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r30,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq30,FF),_mm_mul_pd(vftabscale,rinv30)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 168 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r30,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq30,FF),_mm_mul_pd(vftabscale,rinv30)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 168 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_F,outeriter*24 + inneriter*168);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwCSTab_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCSTab_VdwCSTab_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq11,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq12,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r13,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq13,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq13,FF),_mm_mul_pd(vftabscale,rinv13)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq21,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq22,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r23,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq23,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq23,FF),_mm_mul_pd(vftabscale,rinv23)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r31,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq31,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq31,FF),_mm_mul_pd(vftabscale,rinv31)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r32,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq32,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq32,FF),_mm_mul_pd(vftabscale,rinv32)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r33,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq33,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq33,FF),_mm_mul_pd(vftabscale,rinv33)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 446 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq11,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq12,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r13,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq13,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq13,FF),_mm_mul_pd(vftabscale,rinv13)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq21,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq22,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r23,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq23,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq23,FF),_mm_mul_pd(vftabscale,rinv23)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r31,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq31,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq31,FF),_mm_mul_pd(vftabscale,rinv31)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r32,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq32,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq32,FF),_mm_mul_pd(vftabscale,rinv32)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r33,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq33,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq33,FF),_mm_mul_pd(vftabscale,rinv33)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 446 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_VF,outeriter*26 + inneriter*446);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwCSTab_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCSTab_VdwCSTab_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r13,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq13,FF),_mm_mul_pd(vftabscale,rinv13)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r23,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq23,FF),_mm_mul_pd(vftabscale,rinv23)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r31,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq31,FF),_mm_mul_pd(vftabscale,rinv31)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r32,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq32,FF),_mm_mul_pd(vftabscale,rinv32)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r33,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq33,FF),_mm_mul_pd(vftabscale,rinv33)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 402 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r13,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq13,FF),_mm_mul_pd(vftabscale,rinv13)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r23,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq23,FF),_mm_mul_pd(vftabscale,rinv23)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r31,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq31,FF),_mm_mul_pd(vftabscale,rinv31)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r32,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq32,FF),_mm_mul_pd(vftabscale,rinv32)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r33,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq33,FF),_mm_mul_pd(vftabscale,rinv33)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 402 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_F,outeriter*24 + inneriter*402);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwLJ_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCSTab_VdwLJ_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 56 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 56 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 9 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_VF,outeriter*9 + inneriter*56);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwLJ_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCSTab_VdwLJ_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 47 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 47 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_F,outeriter*7 + inneriter*47);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwLJ_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCSTab_VdwLJ_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 145 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 145 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_VF,outeriter*20 + inneriter*145);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwLJ_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCSTab_VdwLJ_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 128 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 128 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_F,outeriter*18 + inneriter*128);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwLJ_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCSTab_VdwLJ_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r01,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq01,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq01,FF),_mm_mul_pd(vftabscale,rinv01)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r02,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq02,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq02,FF),_mm_mul_pd(vftabscale,rinv02)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq11,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq12,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq21,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq22,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 400 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r01,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq01,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq01,FF),_mm_mul_pd(vftabscale,rinv01)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r02,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq02,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq02,FF),_mm_mul_pd(vftabscale,rinv02)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq11,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq12,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq21,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq22,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 400 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_VF,outeriter*20 + inneriter*400);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwLJ_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCSTab_VdwLJ_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r01,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq01,FF),_mm_mul_pd(vftabscale,rinv01)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r02,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq02,FF),_mm_mul_pd(vftabscale,rinv02)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 359 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r01,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq01,FF),_mm_mul_pd(vftabscale,rinv01)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r02,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq02,FF),_mm_mul_pd(vftabscale,rinv02)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 359 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_F,outeriter*18 + inneriter*359);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwLJ_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCSTab_VdwLJ_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r30,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq30,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq30,FF),_mm_mul_pd(vftabscale,rinv30)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 164 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r30,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq30,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq30,FF),_mm_mul_pd(vftabscale,rinv30)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 164 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_VF,outeriter*26 + inneriter*164);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwLJ_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCSTab_VdwLJ_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r30,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq30,FF),_mm_mul_pd(vftabscale,rinv30)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 147 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r30,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq30,FF),_mm_mul_pd(vftabscale,rinv30)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 147 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_F,outeriter*24 + inneriter*147);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwLJ_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCSTab_VdwLJ_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq11,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq12,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r13,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq13,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq13,FF),_mm_mul_pd(vftabscale,rinv13)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq21,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq22,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r23,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq23,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq23,FF),_mm_mul_pd(vftabscale,rinv23)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r31,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq31,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq31,FF),_mm_mul_pd(vftabscale,rinv31)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r32,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq32,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq32,FF),_mm_mul_pd(vftabscale,rinv32)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r33,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq33,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq33,FF),_mm_mul_pd(vftabscale,rinv33)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 422 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq11,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq12,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r13,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq13,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq13,FF),_mm_mul_pd(vftabscale,rinv13)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq21,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq22,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r23,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq23,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq23,FF),_mm_mul_pd(vftabscale,rinv23)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r31,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq31,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq31,FF),_mm_mul_pd(vftabscale,rinv31)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r32,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq32,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq32,FF),_mm_mul_pd(vftabscale,rinv32)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r33,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq33,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq33,FF),_mm_mul_pd(vftabscale,rinv33)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 422 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_VF,outeriter*26 + inneriter*422);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwLJ_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCSTab_VdwLJ_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r13,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq13,FF),_mm_mul_pd(vftabscale,rinv13)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r23,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq23,FF),_mm_mul_pd(vftabscale,rinv23)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r31,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq31,FF),_mm_mul_pd(vftabscale,rinv31)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r32,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq32,FF),_mm_mul_pd(vftabscale,rinv32)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r33,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq33,FF),_mm_mul_pd(vftabscale,rinv33)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 381 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r13,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq13,FF),_mm_mul_pd(vftabscale,rinv13)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r23,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq23,FF),_mm_mul_pd(vftabscale,rinv23)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r31,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq31,FF),_mm_mul_pd(vftabscale,rinv31)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r32,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq32,FF),_mm_mul_pd(vftabscale,rinv32)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r33,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq33,FF),_mm_mul_pd(vftabscale,rinv33)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 381 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_F,outeriter*24 + inneriter*381);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwNone_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: None
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCSTab_VdwNone_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 43 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 43 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 8 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VF,outeriter*8 + inneriter*43);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwNone_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: None
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCSTab_VdwNone_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 39 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 39 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_F,outeriter*7 + inneriter*39);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwNone_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: None
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCSTab_VdwNone_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 132 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 132 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3_VF,outeriter*19 + inneriter*132);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwNone_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: None
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCSTab_VdwNone_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 120 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 120 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3_F,outeriter*18 + inneriter*120);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwNone_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: None
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCSTab_VdwNone_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ qq00 = _mm_mul_pd(iq0,jq0);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r01,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq01,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq01,FF),_mm_mul_pd(vftabscale,rinv01)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r02,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq02,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq02,FF),_mm_mul_pd(vftabscale,rinv02)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq11,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq12,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq21,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq22,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 387 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r01,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq01,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq01,FF),_mm_mul_pd(vftabscale,rinv01)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r02,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq02,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq02,FF),_mm_mul_pd(vftabscale,rinv02)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq11,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq12,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq21,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq22,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 387 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3W3_VF,outeriter*19 + inneriter*387);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwNone_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: None
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCSTab_VdwNone_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ qq00 = _mm_mul_pd(iq0,jq0);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r01,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq01,FF),_mm_mul_pd(vftabscale,rinv01)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r02,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq02,FF),_mm_mul_pd(vftabscale,rinv02)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 351 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq00,FF),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r01,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq01,FF),_mm_mul_pd(vftabscale,rinv01)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r02,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq02,FF),_mm_mul_pd(vftabscale,rinv02)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 351 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3W3_F,outeriter*18 + inneriter*351);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwNone_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: None
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCSTab_VdwNone_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r30,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq30,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq30,FF),_mm_mul_pd(vftabscale,rinv30)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 132 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq10,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq20,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r30,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq30,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq30,FF),_mm_mul_pd(vftabscale,rinv30)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 132 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4_VF,outeriter*19 + inneriter*132);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwNone_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: None
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCSTab_VdwNone_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r30,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq30,FF),_mm_mul_pd(vftabscale,rinv30)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 120 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r10,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq10,FF),_mm_mul_pd(vftabscale,rinv10)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r20,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq20,FF),_mm_mul_pd(vftabscale,rinv20)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r30,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq30,FF),_mm_mul_pd(vftabscale,rinv30)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 120 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4_F,outeriter*18 + inneriter*120);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwNone_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: None
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCSTab_VdwNone_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA+DIM,x+j_coord_offsetB+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq11,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq12,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r13,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq13,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq13,FF),_mm_mul_pd(vftabscale,rinv13)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq21,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq22,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r23,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq23,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq23,FF),_mm_mul_pd(vftabscale,rinv23)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r31,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq31,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq31,FF),_mm_mul_pd(vftabscale,rinv31)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r32,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq32,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq32,FF),_mm_mul_pd(vftabscale,rinv32)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r33,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq33,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq33,FF),_mm_mul_pd(vftabscale,rinv33)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA+DIM,f+j_coord_offsetB+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 387 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq11,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq12,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r13,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq13,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq13,FF),_mm_mul_pd(vftabscale,rinv13)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq21,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq22,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r23,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq23,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq23,FF),_mm_mul_pd(vftabscale,rinv23)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r31,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq31,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq31,FF),_mm_mul_pd(vftabscale,rinv31)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r32,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq32,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq32,FF),_mm_mul_pd(vftabscale,rinv32)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r33,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq33,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq33,FF),_mm_mul_pd(vftabscale,rinv33)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 387 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4W4_VF,outeriter*19 + inneriter*387);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCSTab_VdwNone_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: CubicSplineTable
+ * VdW interaction: None
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCSTab_VdwNone_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA+DIM,x+j_coord_offsetB+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r13,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq13,FF),_mm_mul_pd(vftabscale,rinv13)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r23,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq23,FF),_mm_mul_pd(vftabscale,rinv23)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r31,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq31,FF),_mm_mul_pd(vftabscale,rinv31)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r32,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq32,FF),_mm_mul_pd(vftabscale,rinv32)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r33,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq33,FF),_mm_mul_pd(vftabscale,rinv33)));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA+DIM,f+j_coord_offsetB+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 351 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r11,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq11,FF),_mm_mul_pd(vftabscale,rinv11)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r12,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq12,FF),_mm_mul_pd(vftabscale,rinv12)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r13,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq13,FF),_mm_mul_pd(vftabscale,rinv13)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r21,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq21,FF),_mm_mul_pd(vftabscale,rinv21)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r22,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq22,FF),_mm_mul_pd(vftabscale,rinv22)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r23,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq23,FF),_mm_mul_pd(vftabscale,rinv23)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r31,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq31,FF),_mm_mul_pd(vftabscale,rinv31)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r32,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq32,FF),_mm_mul_pd(vftabscale,rinv32)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r33,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,2);
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq33,FF),_mm_mul_pd(vftabscale,rinv33)));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 351 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4W4_F,outeriter*18 + inneriter*351);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwCSTab_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: CubicSplineTable
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCoul_VdwCSTab_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 63 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 63 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 9 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_VF,outeriter*9 + inneriter*63);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwCSTab_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: CubicSplineTable
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCoul_VdwCSTab_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 54 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 54 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_F,outeriter*7 + inneriter*54);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwCSTab_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCoul_VdwCSTab_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 122 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 122 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_VF,outeriter*20 + inneriter*122);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwCSTab_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCoul_VdwCSTab_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_F,outeriter*18 + inneriter*111);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwCSTab_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCoul_VdwCSTab_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,rinv01);
+ felec = _mm_mul_pd(velec,rinvsq01);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,rinv02);
+ felec = _mm_mul_pd(velec,rinvsq02);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 287 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,rinv01);
+ felec = _mm_mul_pd(velec,rinvsq01);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,rinv02);
+ felec = _mm_mul_pd(velec,rinvsq02);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 287 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_VF,outeriter*20 + inneriter*287);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwCSTab_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCoul_VdwCSTab_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,rinv01);
+ felec = _mm_mul_pd(velec,rinvsq01);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,rinv02);
+ felec = _mm_mul_pd(velec,rinvsq02);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 270 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,rinv01);
+ felec = _mm_mul_pd(velec,rinvsq01);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,rinv02);
+ felec = _mm_mul_pd(velec,rinvsq02);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 270 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_F,outeriter*18 + inneriter*270);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwCSTab_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCoul_VdwCSTab_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,rinv30);
+ felec = _mm_mul_pd(velec,rinvsq30);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 143 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,rinv30);
+ felec = _mm_mul_pd(velec,rinvsq30);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 143 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_VF,outeriter*26 + inneriter*143);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwCSTab_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCoul_VdwCSTab_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,rinv30);
+ felec = _mm_mul_pd(velec,rinvsq30);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 132 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,rinv30);
+ felec = _mm_mul_pd(velec,rinvsq30);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 132 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_F,outeriter*24 + inneriter*132);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwCSTab_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCoul_VdwCSTab_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,rinv13);
+ felec = _mm_mul_pd(velec,rinvsq13);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,rinv23);
+ felec = _mm_mul_pd(velec,rinvsq23);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,rinv31);
+ felec = _mm_mul_pd(velec,rinvsq31);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,rinv32);
+ felec = _mm_mul_pd(velec,rinvsq32);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,rinv33);
+ felec = _mm_mul_pd(velec,rinvsq33);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 311 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,rinv13);
+ felec = _mm_mul_pd(velec,rinvsq13);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,rinv23);
+ felec = _mm_mul_pd(velec,rinvsq23);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,rinv31);
+ felec = _mm_mul_pd(velec,rinvsq31);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,rinv32);
+ felec = _mm_mul_pd(velec,rinvsq32);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,rinv33);
+ felec = _mm_mul_pd(velec,rinvsq33);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 311 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_VF,outeriter*26 + inneriter*311);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwCSTab_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCoul_VdwCSTab_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,rinv13);
+ felec = _mm_mul_pd(velec,rinvsq13);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,rinv23);
+ felec = _mm_mul_pd(velec,rinvsq23);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,rinv31);
+ felec = _mm_mul_pd(velec,rinvsq31);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,rinv32);
+ felec = _mm_mul_pd(velec,rinvsq32);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,rinv33);
+ felec = _mm_mul_pd(velec,rinvsq33);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 294 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,rinv13);
+ felec = _mm_mul_pd(velec,rinvsq13);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,rinv23);
+ felec = _mm_mul_pd(velec,rinvsq23);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,rinv31);
+ felec = _mm_mul_pd(velec,rinvsq31);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,rinv32);
+ felec = _mm_mul_pd(velec,rinvsq32);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,rinv33);
+ felec = _mm_mul_pd(velec,rinvsq33);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 294 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_F,outeriter*24 + inneriter*294);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwLJ_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCoul_VdwLJ_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 40 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 40 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 9 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_VF,outeriter*9 + inneriter*40);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwLJ_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCoul_VdwLJ_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 34 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 34 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_F,outeriter*7 + inneriter*34);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwLJ_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCoul_VdwLJ_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 99 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 99 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_VF,outeriter*20 + inneriter*99);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwLJ_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCoul_VdwLJ_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 91 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 91 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_F,outeriter*18 + inneriter*91);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwLJ_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCoul_VdwLJ_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,rinv01);
+ felec = _mm_mul_pd(velec,rinvsq01);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,rinv02);
+ felec = _mm_mul_pd(velec,rinvsq02);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 264 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,rinv01);
+ felec = _mm_mul_pd(velec,rinvsq01);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,rinv02);
+ felec = _mm_mul_pd(velec,rinvsq02);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 264 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_VF,outeriter*20 + inneriter*264);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwLJ_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCoul_VdwLJ_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,rinv01);
+ felec = _mm_mul_pd(velec,rinvsq01);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,rinv02);
+ felec = _mm_mul_pd(velec,rinvsq02);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 250 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,rinv01);
+ felec = _mm_mul_pd(velec,rinvsq01);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,rinv02);
+ felec = _mm_mul_pd(velec,rinvsq02);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 250 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_F,outeriter*18 + inneriter*250);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwLJ_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCoul_VdwLJ_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,rinv30);
+ felec = _mm_mul_pd(velec,rinvsq30);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 119 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,rinv30);
+ felec = _mm_mul_pd(velec,rinvsq30);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 119 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_VF,outeriter*26 + inneriter*119);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwLJ_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCoul_VdwLJ_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,rinv30);
+ felec = _mm_mul_pd(velec,rinvsq30);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,rinv30);
+ felec = _mm_mul_pd(velec,rinvsq30);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_F,outeriter*24 + inneriter*111);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwLJ_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCoul_VdwLJ_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,rinv13);
+ felec = _mm_mul_pd(velec,rinvsq13);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,rinv23);
+ felec = _mm_mul_pd(velec,rinvsq23);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,rinv31);
+ felec = _mm_mul_pd(velec,rinvsq31);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,rinv32);
+ felec = _mm_mul_pd(velec,rinvsq32);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,rinv33);
+ felec = _mm_mul_pd(velec,rinvsq33);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 287 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,rinv13);
+ felec = _mm_mul_pd(velec,rinvsq13);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,rinv23);
+ felec = _mm_mul_pd(velec,rinvsq23);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,rinv31);
+ felec = _mm_mul_pd(velec,rinvsq31);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,rinv32);
+ felec = _mm_mul_pd(velec,rinvsq32);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,rinv33);
+ felec = _mm_mul_pd(velec,rinvsq33);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 287 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_VF,outeriter*26 + inneriter*287);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwLJ_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCoul_VdwLJ_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,rinv13);
+ felec = _mm_mul_pd(velec,rinvsq13);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,rinv23);
+ felec = _mm_mul_pd(velec,rinvsq23);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,rinv31);
+ felec = _mm_mul_pd(velec,rinvsq31);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,rinv32);
+ felec = _mm_mul_pd(velec,rinvsq32);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,rinv33);
+ felec = _mm_mul_pd(velec,rinvsq33);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 273 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,rinv13);
+ felec = _mm_mul_pd(velec,rinvsq13);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,rinv23);
+ felec = _mm_mul_pd(velec,rinvsq23);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,rinv31);
+ felec = _mm_mul_pd(velec,rinvsq31);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,rinv32);
+ felec = _mm_mul_pd(velec,rinvsq32);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,rinv33);
+ felec = _mm_mul_pd(velec,rinvsq33);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 273 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_F,outeriter*24 + inneriter*273);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwNone_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: None
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCoul_VdwNone_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 28 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 28 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 8 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VF,outeriter*8 + inneriter*28);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwNone_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: None
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCoul_VdwNone_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 27 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 27 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_F,outeriter*7 + inneriter*27);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwNone_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: None
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCoul_VdwNone_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 87 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 87 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3_VF,outeriter*19 + inneriter*87);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwNone_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: None
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCoul_VdwNone_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 84 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 84 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3_F,outeriter*18 + inneriter*84);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwNone_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: None
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCoul_VdwNone_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ qq00 = _mm_mul_pd(iq0,jq0);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,rinv01);
+ felec = _mm_mul_pd(velec,rinvsq01);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,rinv02);
+ felec = _mm_mul_pd(velec,rinvsq02);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 252 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,rinv01);
+ felec = _mm_mul_pd(velec,rinvsq01);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,rinv02);
+ felec = _mm_mul_pd(velec,rinvsq02);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 252 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3W3_VF,outeriter*19 + inneriter*252);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwNone_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: None
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCoul_VdwNone_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ qq00 = _mm_mul_pd(iq0,jq0);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,rinv01);
+ felec = _mm_mul_pd(velec,rinvsq01);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,rinv02);
+ felec = _mm_mul_pd(velec,rinvsq02);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 243 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(velec,rinvsq00);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,rinv01);
+ felec = _mm_mul_pd(velec,rinvsq01);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,rinv02);
+ felec = _mm_mul_pd(velec,rinvsq02);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 243 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3W3_F,outeriter*18 + inneriter*243);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwNone_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: None
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCoul_VdwNone_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,rinv30);
+ felec = _mm_mul_pd(velec,rinvsq30);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 87 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,rinv30);
+ felec = _mm_mul_pd(velec,rinvsq30);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 87 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4_VF,outeriter*19 + inneriter*87);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwNone_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: None
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCoul_VdwNone_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,rinv30);
+ felec = _mm_mul_pd(velec,rinvsq30);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 84 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,rinv10);
+ felec = _mm_mul_pd(velec,rinvsq10);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,rinv20);
+ felec = _mm_mul_pd(velec,rinvsq20);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,rinv30);
+ felec = _mm_mul_pd(velec,rinvsq30);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 84 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4_F,outeriter*18 + inneriter*84);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwNone_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: None
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecCoul_VdwNone_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA+DIM,x+j_coord_offsetB+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,rinv13);
+ felec = _mm_mul_pd(velec,rinvsq13);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,rinv23);
+ felec = _mm_mul_pd(velec,rinvsq23);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,rinv31);
+ felec = _mm_mul_pd(velec,rinvsq31);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,rinv32);
+ felec = _mm_mul_pd(velec,rinvsq32);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,rinv33);
+ felec = _mm_mul_pd(velec,rinvsq33);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA+DIM,f+j_coord_offsetB+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 252 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,rinv13);
+ felec = _mm_mul_pd(velec,rinvsq13);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,rinv23);
+ felec = _mm_mul_pd(velec,rinvsq23);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,rinv31);
+ felec = _mm_mul_pd(velec,rinvsq31);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,rinv32);
+ felec = _mm_mul_pd(velec,rinvsq32);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,rinv33);
+ felec = _mm_mul_pd(velec,rinvsq33);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 252 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4W4_VF,outeriter*19 + inneriter*252);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecCoul_VdwNone_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: Coulomb
+ * VdW interaction: None
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecCoul_VdwNone_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA+DIM,x+j_coord_offsetB+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,rinv13);
+ felec = _mm_mul_pd(velec,rinvsq13);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,rinv23);
+ felec = _mm_mul_pd(velec,rinvsq23);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,rinv31);
+ felec = _mm_mul_pd(velec,rinvsq31);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,rinv32);
+ felec = _mm_mul_pd(velec,rinvsq32);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,rinv33);
+ felec = _mm_mul_pd(velec,rinvsq33);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA+DIM,f+j_coord_offsetB+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 243 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,rinv11);
+ felec = _mm_mul_pd(velec,rinvsq11);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,rinv12);
+ felec = _mm_mul_pd(velec,rinvsq12);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,rinv13);
+ felec = _mm_mul_pd(velec,rinvsq13);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,rinv21);
+ felec = _mm_mul_pd(velec,rinvsq21);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,rinv22);
+ felec = _mm_mul_pd(velec,rinvsq22);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,rinv23);
+ felec = _mm_mul_pd(velec,rinvsq23);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,rinv31);
+ felec = _mm_mul_pd(velec,rinvsq31);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,rinv32);
+ felec = _mm_mul_pd(velec,rinvsq32);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,rinv33);
+ felec = _mm_mul_pd(velec,rinvsq33);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 243 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4W4_F,outeriter*18 + inneriter*243);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwLJSh_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSh_VdwLJSh_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_sub_pd(rinv00,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 64 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_sub_pd(rinv00,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 64 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 9 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_VF,outeriter*9 + inneriter*64);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwLJSh_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSh_VdwLJSh_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 46 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 46 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_F,outeriter*7 + inneriter*46);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwLJSh_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSh_VdwLJSh_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_sub_pd(rinv00,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_sub_pd(rinv10,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_sub_pd(rinv20,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 159 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_sub_pd(rinv00,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_sub_pd(rinv10,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_sub_pd(rinv20,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 159 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_VF,outeriter*20 + inneriter*159);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwLJSh_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSh_VdwLJSh_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 127 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 127 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_F,outeriter*18 + inneriter*127);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwLJSh_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSh_VdwLJSh_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_sub_pd(rinv00,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_sub_pd(rinv01,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_sub_pd(rinv02,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_sub_pd(rinv10,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_sub_pd(rinv11,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_sub_pd(rinv12,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_sub_pd(rinv20,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_sub_pd(rinv21,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_sub_pd(rinv22,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 432 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_sub_pd(rinv00,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_sub_pd(rinv01,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_sub_pd(rinv02,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_sub_pd(rinv10,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_sub_pd(rinv11,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_sub_pd(rinv12,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_sub_pd(rinv20,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_sub_pd(rinv21,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_sub_pd(rinv22,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 432 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_VF,outeriter*20 + inneriter*432);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwLJSh_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSh_VdwLJSh_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 358 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 358 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_F,outeriter*18 + inneriter*358);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwLJSh_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSh_VdwLJSh_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_sub_pd(rinv10,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_sub_pd(rinv20,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_sub_pd(rinv30,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 182 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_sub_pd(rinv10,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_sub_pd(rinv20,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_sub_pd(rinv30,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 182 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_VF,outeriter*26 + inneriter*182);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwLJSh_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSh_VdwLJSh_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 150 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 150 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_F,outeriter*24 + inneriter*150);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwLJSh_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSh_VdwLJSh_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_sub_pd(rinv11,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_sub_pd(rinv12,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_sub_pd(rinv13,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_sub_pd(rinv21,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_sub_pd(rinv22,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_sub_pd(rinv23,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_sub_pd(rinv31,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_sub_pd(rinv32,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_sub_pd(rinv33,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 458 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_sub_pd(rinv11,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_sub_pd(rinv12,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_sub_pd(rinv13,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_sub_pd(rinv21,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_sub_pd(rinv22,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_sub_pd(rinv23,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_sub_pd(rinv31,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_sub_pd(rinv32,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_sub_pd(rinv33,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 458 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_VF,outeriter*26 + inneriter*458);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwLJSh_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSh_VdwLJSh_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 384 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 384 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_F,outeriter*24 + inneriter*384);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwNone_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSh_VdwNone_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_sub_pd(rinv00,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 46 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_sub_pd(rinv00,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 46 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 8 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VF,outeriter*8 + inneriter*46);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwNone_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSh_VdwNone_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 39 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 39 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_F,outeriter*7 + inneriter*39);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwNone_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSh_VdwNone_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_sub_pd(rinv00,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_sub_pd(rinv10,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_sub_pd(rinv20,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 141 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_sub_pd(rinv00,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_sub_pd(rinv10,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_sub_pd(rinv20,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 141 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3_VF,outeriter*19 + inneriter*141);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwNone_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSh_VdwNone_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 120 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 120 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3_F,outeriter*18 + inneriter*120);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwNone_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSh_VdwNone_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ qq00 = _mm_mul_pd(iq0,jq0);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_sub_pd(rinv00,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_sub_pd(rinv01,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_sub_pd(rinv02,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_sub_pd(rinv10,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_sub_pd(rinv11,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_sub_pd(rinv12,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_sub_pd(rinv20,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_sub_pd(rinv21,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_sub_pd(rinv22,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 414 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_sub_pd(rinv00,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_sub_pd(rinv01,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_sub_pd(rinv02,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_sub_pd(rinv10,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_sub_pd(rinv11,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_sub_pd(rinv12,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_sub_pd(rinv20,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_sub_pd(rinv21,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_sub_pd(rinv22,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 414 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3W3_VF,outeriter*19 + inneriter*414);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwNone_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSh_VdwNone_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ qq00 = _mm_mul_pd(iq0,jq0);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 351 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 351 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3W3_F,outeriter*18 + inneriter*351);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwNone_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSh_VdwNone_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_sub_pd(rinv10,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_sub_pd(rinv20,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_sub_pd(rinv30,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 141 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_sub_pd(rinv10,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_sub_pd(rinv20,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_sub_pd(rinv30,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 141 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4_VF,outeriter*19 + inneriter*141);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwNone_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSh_VdwNone_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 120 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 120 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4_F,outeriter*18 + inneriter*120);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwNone_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSh_VdwNone_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA+DIM,x+j_coord_offsetB+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_sub_pd(rinv11,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_sub_pd(rinv12,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_sub_pd(rinv13,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_sub_pd(rinv21,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_sub_pd(rinv22,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_sub_pd(rinv23,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_sub_pd(rinv31,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_sub_pd(rinv32,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_sub_pd(rinv33,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA+DIM,f+j_coord_offsetB+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 414 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_sub_pd(rinv11,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_sub_pd(rinv12,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_sub_pd(rinv13,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_sub_pd(rinv21,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_sub_pd(rinv22,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_sub_pd(rinv23,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_sub_pd(rinv31,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_sub_pd(rinv32,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_sub_pd(rinv33,sh_ewald),velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 414 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4W4_VF,outeriter*19 + inneriter*414);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSh_VdwNone_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSh_VdwNone_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA+DIM,x+j_coord_offsetB+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA+DIM,f+j_coord_offsetB+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 351 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 351 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4W4_F,outeriter*18 + inneriter*351);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwLJSw_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSw_VdwLJSw_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 83 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 83 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 9 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_VF,outeriter*9 + inneriter*83);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwLJSw_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSw_VdwLJSw_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 77 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 77 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_F,outeriter*7 + inneriter*77);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwLJSw_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSw_VdwLJSw_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 216 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 216 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_VF,outeriter*20 + inneriter*216);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwLJSw_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSw_VdwLJSw_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 204 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 204 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_F,outeriter*18 + inneriter*204);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwLJSw_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSw_VdwLJSw_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(rinv01,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ d = _mm_sub_pd(r01,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv01,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(rinv02,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ d = _mm_sub_pd(r02,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv02,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ d = _mm_sub_pd(r11,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv11,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ d = _mm_sub_pd(r12,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv12,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ d = _mm_sub_pd(r21,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv21,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ d = _mm_sub_pd(r22,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv22,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 603 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(rinv01,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ d = _mm_sub_pd(r01,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv01,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(rinv02,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ d = _mm_sub_pd(r02,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv02,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ d = _mm_sub_pd(r11,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv11,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ d = _mm_sub_pd(r12,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv12,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ d = _mm_sub_pd(r21,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv21,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ d = _mm_sub_pd(r22,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv22,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 603 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_VF,outeriter*20 + inneriter*603);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwLJSw_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSw_VdwLJSw_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(rinv01,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ d = _mm_sub_pd(r01,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv01,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(rinv02,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ d = _mm_sub_pd(r02,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv02,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ d = _mm_sub_pd(r11,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv11,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ d = _mm_sub_pd(r12,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv12,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ d = _mm_sub_pd(r21,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv21,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ d = _mm_sub_pd(r22,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv22,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 573 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(rinv01,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ d = _mm_sub_pd(r01,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv01,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(rinv02,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ d = _mm_sub_pd(r02,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv02,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ d = _mm_sub_pd(r11,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv11,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ d = _mm_sub_pd(r12,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv12,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ d = _mm_sub_pd(r21,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv21,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ d = _mm_sub_pd(r22,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv22,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 573 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_F,outeriter*18 + inneriter*573);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwLJSw_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSw_VdwLJSw_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(rinv30,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ d = _mm_sub_pd(r30,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv30,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 257 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(rinv30,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ d = _mm_sub_pd(r30,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv30,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 257 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_VF,outeriter*26 + inneriter*257);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwLJSw_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSw_VdwLJSw_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(rinv30,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ d = _mm_sub_pd(r30,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv30,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 245 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(rinv30,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ d = _mm_sub_pd(r30,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv30,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 245 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_F,outeriter*24 + inneriter*245);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwLJSw_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSw_VdwLJSw_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ d = _mm_sub_pd(r11,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv11,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ d = _mm_sub_pd(r12,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv12,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(rinv13,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ d = _mm_sub_pd(r13,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv13,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ d = _mm_sub_pd(r21,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv21,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ d = _mm_sub_pd(r22,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv22,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(rinv23,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ d = _mm_sub_pd(r23,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv23,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(rinv31,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ d = _mm_sub_pd(r31,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv31,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(rinv32,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ d = _mm_sub_pd(r32,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv32,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(rinv33,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ d = _mm_sub_pd(r33,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv33,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 647 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ d = _mm_sub_pd(r11,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv11,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ d = _mm_sub_pd(r12,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv12,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(rinv13,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ d = _mm_sub_pd(r13,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv13,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ d = _mm_sub_pd(r21,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv21,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ d = _mm_sub_pd(r22,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv22,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(rinv23,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ d = _mm_sub_pd(r23,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv23,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(rinv31,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ d = _mm_sub_pd(r31,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv31,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(rinv32,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ d = _mm_sub_pd(r32,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv32,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(rinv33,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ d = _mm_sub_pd(r33,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv33,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 647 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_VF,outeriter*26 + inneriter*647);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwLJSw_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSw_VdwLJSw_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ d = _mm_sub_pd(r11,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv11,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ d = _mm_sub_pd(r12,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv12,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(rinv13,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ d = _mm_sub_pd(r13,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv13,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ d = _mm_sub_pd(r21,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv21,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ d = _mm_sub_pd(r22,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv22,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(rinv23,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ d = _mm_sub_pd(r23,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv23,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(rinv31,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ d = _mm_sub_pd(r31,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv31,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(rinv32,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ d = _mm_sub_pd(r32,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv32,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(rinv33,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ d = _mm_sub_pd(r33,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv33,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 617 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ d = _mm_sub_pd(r11,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv11,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ d = _mm_sub_pd(r12,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv12,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(rinv13,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ d = _mm_sub_pd(r13,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv13,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ d = _mm_sub_pd(r21,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv21,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ d = _mm_sub_pd(r22,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv22,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(rinv23,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ d = _mm_sub_pd(r23,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv23,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(rinv31,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ d = _mm_sub_pd(r31,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv31,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(rinv32,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ d = _mm_sub_pd(r32,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv32,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(rinv33,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ d = _mm_sub_pd(r33,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv33,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 617 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_F,outeriter*24 + inneriter*617);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwNone_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSw_VdwNone_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 65 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 65 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 8 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VF,outeriter*8 + inneriter*65);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwNone_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSw_VdwNone_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 62 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 62 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_F,outeriter*7 + inneriter*62);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwNone_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSw_VdwNone_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 198 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 198 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3_VF,outeriter*19 + inneriter*198);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwNone_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSw_VdwNone_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 189 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 189 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3_F,outeriter*18 + inneriter*189);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwNone_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSw_VdwNone_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ qq00 = _mm_mul_pd(iq0,jq0);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(rinv01,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ d = _mm_sub_pd(r01,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv01,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(rinv02,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ d = _mm_sub_pd(r02,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv02,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ d = _mm_sub_pd(r11,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv11,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ d = _mm_sub_pd(r12,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv12,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ d = _mm_sub_pd(r21,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv21,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ d = _mm_sub_pd(r22,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv22,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 585 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(rinv01,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ d = _mm_sub_pd(r01,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv01,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(rinv02,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ d = _mm_sub_pd(r02,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv02,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ d = _mm_sub_pd(r11,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv11,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ d = _mm_sub_pd(r12,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv12,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ d = _mm_sub_pd(r21,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv21,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ d = _mm_sub_pd(r22,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv22,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 585 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3W3_VF,outeriter*19 + inneriter*585);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwNone_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSw_VdwNone_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ qq00 = _mm_mul_pd(iq0,jq0);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(rinv01,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ d = _mm_sub_pd(r01,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv01,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(rinv02,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ d = _mm_sub_pd(r02,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv02,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ d = _mm_sub_pd(r11,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv11,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ d = _mm_sub_pd(r12,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv12,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ d = _mm_sub_pd(r21,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv21,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ d = _mm_sub_pd(r22,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv22,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 558 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(rinv01,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ d = _mm_sub_pd(r01,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv01,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(rinv02,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ d = _mm_sub_pd(r02,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv02,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ d = _mm_sub_pd(r11,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv11,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ d = _mm_sub_pd(r12,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv12,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ d = _mm_sub_pd(r21,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv21,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ d = _mm_sub_pd(r22,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv22,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 558 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3W3_F,outeriter*18 + inneriter*558);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwNone_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSw_VdwNone_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(rinv30,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ d = _mm_sub_pd(r30,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv30,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 198 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(rinv30,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ d = _mm_sub_pd(r30,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv30,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 198 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4_VF,outeriter*19 + inneriter*198);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwNone_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSw_VdwNone_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(rinv30,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ d = _mm_sub_pd(r30,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv30,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 189 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ d = _mm_sub_pd(r10,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv10,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ d = _mm_sub_pd(r20,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv20,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(rinv30,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ d = _mm_sub_pd(r30,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv30,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 189 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4_F,outeriter*18 + inneriter*189);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwNone_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEwSw_VdwNone_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA+DIM,x+j_coord_offsetB+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ d = _mm_sub_pd(r11,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv11,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ d = _mm_sub_pd(r12,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv12,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(rinv13,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ d = _mm_sub_pd(r13,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv13,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ d = _mm_sub_pd(r21,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv21,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ d = _mm_sub_pd(r22,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv22,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(rinv23,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ d = _mm_sub_pd(r23,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv23,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(rinv31,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ d = _mm_sub_pd(r31,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv31,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(rinv32,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ d = _mm_sub_pd(r32,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv32,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(rinv33,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ d = _mm_sub_pd(r33,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv33,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA+DIM,f+j_coord_offsetB+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 585 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ d = _mm_sub_pd(r11,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv11,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ d = _mm_sub_pd(r12,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv12,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(rinv13,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ d = _mm_sub_pd(r13,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv13,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ d = _mm_sub_pd(r21,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv21,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ d = _mm_sub_pd(r22,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv22,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(rinv23,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ d = _mm_sub_pd(r23,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv23,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(rinv31,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ d = _mm_sub_pd(r31,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv31,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(rinv32,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ d = _mm_sub_pd(r32,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv32,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(rinv33,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ d = _mm_sub_pd(r33,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv33,_mm_mul_pd(velec,dsw)) );
+ velec = _mm_mul_pd(velec,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 585 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4W4_VF,outeriter*19 + inneriter*585);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEwSw_VdwNone_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEwSw_VdwNone_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA+DIM,x+j_coord_offsetB+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ d = _mm_sub_pd(r11,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv11,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ d = _mm_sub_pd(r12,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv12,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(rinv13,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ d = _mm_sub_pd(r13,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv13,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ d = _mm_sub_pd(r21,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv21,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ d = _mm_sub_pd(r22,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv22,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(rinv23,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ d = _mm_sub_pd(r23,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv23,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(rinv31,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ d = _mm_sub_pd(r31,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv31,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(rinv32,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ d = _mm_sub_pd(r32,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv32,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(rinv33,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ d = _mm_sub_pd(r33,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv33,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA+DIM,f+j_coord_offsetB+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 558 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ d = _mm_sub_pd(r11,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv11,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ d = _mm_sub_pd(r12,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv12,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(rinv13,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ d = _mm_sub_pd(r13,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv13,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ d = _mm_sub_pd(r21,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv21,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ d = _mm_sub_pd(r22,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv22,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(rinv23,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ d = _mm_sub_pd(r23,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv23,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(rinv31,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ d = _mm_sub_pd(r31,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv31,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(rinv32,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ d = _mm_sub_pd(r32,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv32,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(rinv33,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ d = _mm_sub_pd(r33,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv33,_mm_mul_pd(velec,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 558 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4W4_F,outeriter*18 + inneriter*558);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwCSTab_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: CubicSplineTable
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEw_VdwCSTab_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 75 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 75 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 9 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_VF,outeriter*9 + inneriter*75);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwCSTab_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: CubicSplineTable
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEw_VdwCSTab_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 62 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 62 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_F,outeriter*7 + inneriter*62);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwCSTab_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEw_VdwCSTab_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 160 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 160 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_VF,outeriter*20 + inneriter*160);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwCSTab_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEw_VdwCSTab_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 137 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 137 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_F,outeriter*18 + inneriter*137);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwCSTab_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEw_VdwCSTab_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(rinv01,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(rinv02,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 403 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(rinv01,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(rinv02,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 403 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_VF,outeriter*20 + inneriter*403);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwCSTab_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEw_VdwCSTab_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 350 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 350 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_F,outeriter*18 + inneriter*350);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwCSTab_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEw_VdwCSTab_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(rinv30,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 182 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(rinv30,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 182 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_VF,outeriter*26 + inneriter*182);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwCSTab_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEw_VdwCSTab_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 159 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 159 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_F,outeriter*24 + inneriter*159);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwCSTab_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEw_VdwCSTab_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(rinv13,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(rinv23,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(rinv31,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(rinv32,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(rinv33,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 428 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(rinv13,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(rinv23,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(rinv31,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(rinv32,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(rinv33,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 428 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_VF,outeriter*26 + inneriter*428);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwCSTab_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEw_VdwCSTab_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 375 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 375 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_F,outeriter*24 + inneriter*375);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwLJ_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEw_VdwLJ_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 53 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 53 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 9 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_VF,outeriter*9 + inneriter*53);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwLJ_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEw_VdwLJ_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 43 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 43 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_F,outeriter*7 + inneriter*43);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwLJ_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEw_VdwLJ_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 138 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 138 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_VF,outeriter*20 + inneriter*138);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwLJ_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEw_VdwLJ_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 118 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 118 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_F,outeriter*18 + inneriter*118);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwLJ_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEw_VdwLJ_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(rinv01,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(rinv02,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 381 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(rinv01,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(rinv02,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 381 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_VF,outeriter*20 + inneriter*381);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwLJ_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEw_VdwLJ_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 331 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 331 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_F,outeriter*18 + inneriter*331);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwLJ_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEw_VdwLJ_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(rinv30,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 158 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(rinv30,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 158 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_VF,outeriter*26 + inneriter*158);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwLJ_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEw_VdwLJ_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 138 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 138 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_F,outeriter*24 + inneriter*138);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwLJ_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEw_VdwLJ_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(rinv13,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(rinv23,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(rinv31,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(rinv32,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(rinv33,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 404 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(rinv13,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(rinv23,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(rinv31,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(rinv32,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(rinv33,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 404 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_VF,outeriter*26 + inneriter*404);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwLJ_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEw_VdwLJ_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 354 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 354 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_F,outeriter*24 + inneriter*354);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwNone_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEw_VdwNone_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 41 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 41 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 8 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VF,outeriter*8 + inneriter*41);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwNone_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEw_VdwNone_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 36 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 36 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_F,outeriter*7 + inneriter*36);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwNone_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEw_VdwNone_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 126 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 126 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3_VF,outeriter*19 + inneriter*126);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwNone_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEw_VdwNone_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3_F,outeriter*18 + inneriter*111);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwNone_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEw_VdwNone_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ qq00 = _mm_mul_pd(iq0,jq0);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(rinv01,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(rinv02,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 369 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(rinv00,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(rinv01,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(rinv02,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 369 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3W3_VF,outeriter*19 + inneriter*369);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwNone_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEw_VdwNone_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ qq00 = _mm_mul_pd(iq0,jq0);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 324 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r00,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r01 = _mm_mul_pd(rsq01,rinv01);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r01,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r02 = _mm_mul_pd(rsq02,rinv02);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r02,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 324 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3W3_F,outeriter*18 + inneriter*324);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwNone_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEw_VdwNone_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(rinv30,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 126 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(rinv10,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(rinv20,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(rinv30,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 126 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4_VF,outeriter*19 + inneriter*126);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwNone_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEw_VdwNone_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r10 = _mm_mul_pd(rsq10,rinv10);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r10,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r20 = _mm_mul_pd(rsq20,rinv20);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r20,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r30 = _mm_mul_pd(rsq30,rinv30);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r30,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq30,rinv30),_mm_sub_pd(rinvsq30,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4_F,outeriter*18 + inneriter*111);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwNone_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecEw_VdwNone_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA+DIM,x+j_coord_offsetB+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(rinv13,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(rinv23,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(rinv31,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(rinv32,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(rinv33,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA+DIM,f+j_coord_offsetB+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 369 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(rinv11,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(rinv12,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(rinv13,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(rinv21,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(rinv22,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(rinv23,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(rinv31,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(rinv32,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ ewtabD = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ ewtabFn = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(rinv33,velec));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 369 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4W4_VF,outeriter*19 + inneriter*369);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecEw_VdwNone_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: Ewald
+ * VdW interaction: None
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecEw_VdwNone_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA+DIM,x+j_coord_offsetB+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA+DIM,f+j_coord_offsetB+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 324 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r11 = _mm_mul_pd(rsq11,rinv11);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r11,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r12 = _mm_mul_pd(rsq12,rinv12);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r12,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r13 = _mm_mul_pd(rsq13,rinv13);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r13,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq13,rinv13),_mm_sub_pd(rinvsq13,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r21 = _mm_mul_pd(rsq21,rinv21);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r21,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r22 = _mm_mul_pd(rsq22,rinv22);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r22,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r23 = _mm_mul_pd(rsq23,rinv23);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r23,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq23,rinv23),_mm_sub_pd(rinvsq23,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r31 = _mm_mul_pd(rsq31,rinv31);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r31,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq31,rinv31),_mm_sub_pd(rinvsq31,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r32 = _mm_mul_pd(rsq32,rinv32);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r32,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq32,rinv32),_mm_sub_pd(rinvsq32,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r33 = _mm_mul_pd(rsq33,rinv33);
+
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r33,ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq33,rinv33),_mm_sub_pd(rinvsq33,felec));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 324 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4W4_F,outeriter*18 + inneriter*324);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecGB_VdwCSTab_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: GeneralizedBorn
+ * VdW interaction: CubicSplineTable
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecGB_VdwCSTab_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i gbitab;
+ __m128d vgb,fgb,vgbsum,dvdasum,gbscale,gbtabscale,isaprod,gbqqfactor,gbinvepsdiff,dvdaj,gbeps,dvdatmp;
+ __m128d minushalf = _mm_set1_pd(-0.5);
+ real *invsqrta,*dvda,*gbtab;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ invsqrta = fr->invsqrta;
+ dvda = fr->dvda;
+ gbtabscale = _mm_set1_pd(fr->gbtab.scale);
+ gbtab = fr->gbtab.data;
+ gbinvepsdiff = _mm_set1_pd((1.0/fr->epsilon_r) - (1.0/fr->gb_epsilon_solvent));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ isai0 = _mm_load1_pd(invsqrta+inr+0);
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vgbsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+ dvdasum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ isaj0 = gmx_mm_load_2real_swizzle_pd(invsqrta+jnrA+0,invsqrta+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* GENERALIZED BORN AND COULOMB ELECTROSTATICS */
+ isaprod = _mm_mul_pd(isai0,isaj0);
+ gbqqfactor = _mm_xor_pd(signbit,_mm_mul_pd(qq00,_mm_mul_pd(isaprod,gbinvepsdiff)));
+ gbscale = _mm_mul_pd(isaprod,gbtabscale);
+
+ /* Calculate generalized born table index - this is a separate table from the normal one,
+ * but we use the same procedure by multiplying r with scale and truncating to integer.
+ */
+ rt = _mm_mul_pd(r00,gbscale);
+ gbitab = _mm_cvttpd_epi32(rt);
+ gbeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(gbitab));
+ gbitab = _mm_slli_epi32(gbitab,2);
+
+ Y = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) );
+ F = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) +2);
+ H = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(gbeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(gbeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(gbeps,Fp));
+ vgb = _mm_mul_pd(gbqqfactor,VV);
+
+ FF = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fgb = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
+ dvdatmp = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+ dvdasum = _mm_add_pd(dvdasum,dvdatmp);
+ gmx_mm_increment_2real_swizzle_pd(dvda+jnrA,dvda+jnrB,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(velec,rinv00),fgb),rinv00);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vgbsum = _mm_add_pd(vgbsum,vgb);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 92 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ isaj0 = _mm_load_sd(invsqrta+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* GENERALIZED BORN AND COULOMB ELECTROSTATICS */
+ isaprod = _mm_mul_pd(isai0,isaj0);
+ gbqqfactor = _mm_xor_pd(signbit,_mm_mul_pd(qq00,_mm_mul_pd(isaprod,gbinvepsdiff)));
+ gbscale = _mm_mul_pd(isaprod,gbtabscale);
+
+ /* Calculate generalized born table index - this is a separate table from the normal one,
+ * but we use the same procedure by multiplying r with scale and truncating to integer.
+ */
+ rt = _mm_mul_pd(r00,gbscale);
+ gbitab = _mm_cvttpd_epi32(rt);
+ gbeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(gbitab));
+ gbitab = _mm_slli_epi32(gbitab,2);
+
+ Y = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(gbeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(gbeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(gbeps,Fp));
+ vgb = _mm_mul_pd(gbqqfactor,VV);
+
+ FF = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fgb = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
+ dvdatmp = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+ dvdasum = _mm_add_pd(dvdasum,dvdatmp);
+ gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(velec,rinv00),fgb),rinv00);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vgb = _mm_unpacklo_pd(vgb,_mm_setzero_pd());
+ vgbsum = _mm_add_pd(vgbsum,vgb);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 92 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vgbsum,kernel_data->energygrp_polarization+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+ dvdasum = _mm_mul_pd(dvdasum, _mm_mul_pd(isai0,isai0));
+ gmx_mm_update_1pot_pd(dvdasum,dvda+inr);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 10 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_VF,outeriter*10 + inneriter*92);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecGB_VdwCSTab_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: GeneralizedBorn
+ * VdW interaction: CubicSplineTable
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecGB_VdwCSTab_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i gbitab;
+ __m128d vgb,fgb,vgbsum,dvdasum,gbscale,gbtabscale,isaprod,gbqqfactor,gbinvepsdiff,dvdaj,gbeps,dvdatmp;
+ __m128d minushalf = _mm_set1_pd(-0.5);
+ real *invsqrta,*dvda,*gbtab;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ invsqrta = fr->invsqrta;
+ dvda = fr->dvda;
+ gbtabscale = _mm_set1_pd(fr->gbtab.scale);
+ gbtab = fr->gbtab.data;
+ gbinvepsdiff = _mm_set1_pd((1.0/fr->epsilon_r) - (1.0/fr->gb_epsilon_solvent));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ isai0 = _mm_load1_pd(invsqrta+inr+0);
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ dvdasum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ isaj0 = gmx_mm_load_2real_swizzle_pd(invsqrta+jnrA+0,invsqrta+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* GENERALIZED BORN AND COULOMB ELECTROSTATICS */
+ isaprod = _mm_mul_pd(isai0,isaj0);
+ gbqqfactor = _mm_xor_pd(signbit,_mm_mul_pd(qq00,_mm_mul_pd(isaprod,gbinvepsdiff)));
+ gbscale = _mm_mul_pd(isaprod,gbtabscale);
+
+ /* Calculate generalized born table index - this is a separate table from the normal one,
+ * but we use the same procedure by multiplying r with scale and truncating to integer.
+ */
+ rt = _mm_mul_pd(r00,gbscale);
+ gbitab = _mm_cvttpd_epi32(rt);
+ gbeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(gbitab));
+ gbitab = _mm_slli_epi32(gbitab,2);
+
+ Y = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) );
+ F = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) +2);
+ H = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(gbeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(gbeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(gbeps,Fp));
+ vgb = _mm_mul_pd(gbqqfactor,VV);
+
+ FF = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fgb = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
+ dvdatmp = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+ dvdasum = _mm_add_pd(dvdasum,dvdatmp);
+ gmx_mm_increment_2real_swizzle_pd(dvda+jnrA,dvda+jnrB,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(velec,rinv00),fgb),rinv00);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 82 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ isaj0 = _mm_load_sd(invsqrta+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* GENERALIZED BORN AND COULOMB ELECTROSTATICS */
+ isaprod = _mm_mul_pd(isai0,isaj0);
+ gbqqfactor = _mm_xor_pd(signbit,_mm_mul_pd(qq00,_mm_mul_pd(isaprod,gbinvepsdiff)));
+ gbscale = _mm_mul_pd(isaprod,gbtabscale);
+
+ /* Calculate generalized born table index - this is a separate table from the normal one,
+ * but we use the same procedure by multiplying r with scale and truncating to integer.
+ */
+ rt = _mm_mul_pd(r00,gbscale);
+ gbitab = _mm_cvttpd_epi32(rt);
+ gbeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(gbitab));
+ gbitab = _mm_slli_epi32(gbitab,2);
+
+ Y = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(gbeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(gbeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(gbeps,Fp));
+ vgb = _mm_mul_pd(gbqqfactor,VV);
+
+ FF = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fgb = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
+ dvdatmp = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+ dvdasum = _mm_add_pd(dvdasum,dvdatmp);
+ gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(velec,rinv00),fgb),rinv00);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 82 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ dvdasum = _mm_mul_pd(dvdasum, _mm_mul_pd(isai0,isai0));
+ gmx_mm_update_1pot_pd(dvdasum,dvda+inr);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_F,outeriter*7 + inneriter*82);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecGB_VdwLJ_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: GeneralizedBorn
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecGB_VdwLJ_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i gbitab;
+ __m128d vgb,fgb,vgbsum,dvdasum,gbscale,gbtabscale,isaprod,gbqqfactor,gbinvepsdiff,dvdaj,gbeps,dvdatmp;
+ __m128d minushalf = _mm_set1_pd(-0.5);
+ real *invsqrta,*dvda,*gbtab;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ invsqrta = fr->invsqrta;
+ dvda = fr->dvda;
+ gbtabscale = _mm_set1_pd(fr->gbtab.scale);
+ gbtab = fr->gbtab.data;
+ gbinvepsdiff = _mm_set1_pd((1.0/fr->epsilon_r) - (1.0/fr->gb_epsilon_solvent));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ isai0 = _mm_load1_pd(invsqrta+inr+0);
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vgbsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+ dvdasum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ isaj0 = gmx_mm_load_2real_swizzle_pd(invsqrta+jnrA+0,invsqrta+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* GENERALIZED BORN AND COULOMB ELECTROSTATICS */
+ isaprod = _mm_mul_pd(isai0,isaj0);
+ gbqqfactor = _mm_xor_pd(signbit,_mm_mul_pd(qq00,_mm_mul_pd(isaprod,gbinvepsdiff)));
+ gbscale = _mm_mul_pd(isaprod,gbtabscale);
+
+ /* Calculate generalized born table index - this is a separate table from the normal one,
+ * but we use the same procedure by multiplying r with scale and truncating to integer.
+ */
+ rt = _mm_mul_pd(r00,gbscale);
+ gbitab = _mm_cvttpd_epi32(rt);
+ gbeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(gbitab));
+ gbitab = _mm_slli_epi32(gbitab,2);
+
+ Y = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) );
+ F = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) +2);
+ H = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(gbeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(gbeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(gbeps,Fp));
+ vgb = _mm_mul_pd(gbqqfactor,VV);
+
+ FF = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fgb = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
+ dvdatmp = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+ dvdasum = _mm_add_pd(dvdasum,dvdatmp);
+ gmx_mm_increment_2real_swizzle_pd(dvda+jnrA,dvda+jnrB,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(velec,rinv00),fgb),rinv00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vgbsum = _mm_add_pd(vgbsum,vgb);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 71 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ isaj0 = _mm_load_sd(invsqrta+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* GENERALIZED BORN AND COULOMB ELECTROSTATICS */
+ isaprod = _mm_mul_pd(isai0,isaj0);
+ gbqqfactor = _mm_xor_pd(signbit,_mm_mul_pd(qq00,_mm_mul_pd(isaprod,gbinvepsdiff)));
+ gbscale = _mm_mul_pd(isaprod,gbtabscale);
+
+ /* Calculate generalized born table index - this is a separate table from the normal one,
+ * but we use the same procedure by multiplying r with scale and truncating to integer.
+ */
+ rt = _mm_mul_pd(r00,gbscale);
+ gbitab = _mm_cvttpd_epi32(rt);
+ gbeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(gbitab));
+ gbitab = _mm_slli_epi32(gbitab,2);
+
+ Y = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(gbeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(gbeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(gbeps,Fp));
+ vgb = _mm_mul_pd(gbqqfactor,VV);
+
+ FF = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fgb = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
+ dvdatmp = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+ dvdasum = _mm_add_pd(dvdasum,dvdatmp);
+ gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(velec,rinv00),fgb),rinv00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vgb = _mm_unpacklo_pd(vgb,_mm_setzero_pd());
+ vgbsum = _mm_add_pd(vgbsum,vgb);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 71 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vgbsum,kernel_data->energygrp_polarization+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+ dvdasum = _mm_mul_pd(dvdasum, _mm_mul_pd(isai0,isai0));
+ gmx_mm_update_1pot_pd(dvdasum,dvda+inr);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 10 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_VF,outeriter*10 + inneriter*71);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecGB_VdwLJ_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: GeneralizedBorn
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecGB_VdwLJ_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i gbitab;
+ __m128d vgb,fgb,vgbsum,dvdasum,gbscale,gbtabscale,isaprod,gbqqfactor,gbinvepsdiff,dvdaj,gbeps,dvdatmp;
+ __m128d minushalf = _mm_set1_pd(-0.5);
+ real *invsqrta,*dvda,*gbtab;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ invsqrta = fr->invsqrta;
+ dvda = fr->dvda;
+ gbtabscale = _mm_set1_pd(fr->gbtab.scale);
+ gbtab = fr->gbtab.data;
+ gbinvepsdiff = _mm_set1_pd((1.0/fr->epsilon_r) - (1.0/fr->gb_epsilon_solvent));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ isai0 = _mm_load1_pd(invsqrta+inr+0);
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ dvdasum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ isaj0 = gmx_mm_load_2real_swizzle_pd(invsqrta+jnrA+0,invsqrta+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* GENERALIZED BORN AND COULOMB ELECTROSTATICS */
+ isaprod = _mm_mul_pd(isai0,isaj0);
+ gbqqfactor = _mm_xor_pd(signbit,_mm_mul_pd(qq00,_mm_mul_pd(isaprod,gbinvepsdiff)));
+ gbscale = _mm_mul_pd(isaprod,gbtabscale);
+
+ /* Calculate generalized born table index - this is a separate table from the normal one,
+ * but we use the same procedure by multiplying r with scale and truncating to integer.
+ */
+ rt = _mm_mul_pd(r00,gbscale);
+ gbitab = _mm_cvttpd_epi32(rt);
+ gbeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(gbitab));
+ gbitab = _mm_slli_epi32(gbitab,2);
+
+ Y = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) );
+ F = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) +2);
+ H = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(gbeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(gbeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(gbeps,Fp));
+ vgb = _mm_mul_pd(gbqqfactor,VV);
+
+ FF = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fgb = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
+ dvdatmp = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+ dvdasum = _mm_add_pd(dvdasum,dvdatmp);
+ gmx_mm_increment_2real_swizzle_pd(dvda+jnrA,dvda+jnrB,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(velec,rinv00),fgb),rinv00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 64 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ isaj0 = _mm_load_sd(invsqrta+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* GENERALIZED BORN AND COULOMB ELECTROSTATICS */
+ isaprod = _mm_mul_pd(isai0,isaj0);
+ gbqqfactor = _mm_xor_pd(signbit,_mm_mul_pd(qq00,_mm_mul_pd(isaprod,gbinvepsdiff)));
+ gbscale = _mm_mul_pd(isaprod,gbtabscale);
+
+ /* Calculate generalized born table index - this is a separate table from the normal one,
+ * but we use the same procedure by multiplying r with scale and truncating to integer.
+ */
+ rt = _mm_mul_pd(r00,gbscale);
+ gbitab = _mm_cvttpd_epi32(rt);
+ gbeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(gbitab));
+ gbitab = _mm_slli_epi32(gbitab,2);
+
+ Y = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(gbeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(gbeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(gbeps,Fp));
+ vgb = _mm_mul_pd(gbqqfactor,VV);
+
+ FF = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fgb = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
+ dvdatmp = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+ dvdasum = _mm_add_pd(dvdasum,dvdatmp);
+ gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(velec,rinv00),fgb),rinv00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 64 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ dvdasum = _mm_mul_pd(dvdasum, _mm_mul_pd(isai0,isai0));
+ gmx_mm_update_1pot_pd(dvdasum,dvda+inr);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_F,outeriter*7 + inneriter*64);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecGB_VdwNone_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: GeneralizedBorn
+ * VdW interaction: None
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecGB_VdwNone_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i gbitab;
+ __m128d vgb,fgb,vgbsum,dvdasum,gbscale,gbtabscale,isaprod,gbqqfactor,gbinvepsdiff,dvdaj,gbeps,dvdatmp;
+ __m128d minushalf = _mm_set1_pd(-0.5);
+ real *invsqrta,*dvda,*gbtab;
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ invsqrta = fr->invsqrta;
+ dvda = fr->dvda;
+ gbtabscale = _mm_set1_pd(fr->gbtab.scale);
+ gbtab = fr->gbtab.data;
+ gbinvepsdiff = _mm_set1_pd((1.0/fr->epsilon_r) - (1.0/fr->gb_epsilon_solvent));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ isai0 = _mm_load1_pd(invsqrta+inr+0);
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vgbsum = _mm_setzero_pd();
+ dvdasum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ isaj0 = gmx_mm_load_2real_swizzle_pd(invsqrta+jnrA+0,invsqrta+jnrB+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* GENERALIZED BORN AND COULOMB ELECTROSTATICS */
+ isaprod = _mm_mul_pd(isai0,isaj0);
+ gbqqfactor = _mm_xor_pd(signbit,_mm_mul_pd(qq00,_mm_mul_pd(isaprod,gbinvepsdiff)));
+ gbscale = _mm_mul_pd(isaprod,gbtabscale);
+
+ /* Calculate generalized born table index - this is a separate table from the normal one,
+ * but we use the same procedure by multiplying r with scale and truncating to integer.
+ */
+ rt = _mm_mul_pd(r00,gbscale);
+ gbitab = _mm_cvttpd_epi32(rt);
+ gbeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(gbitab));
+ gbitab = _mm_slli_epi32(gbitab,2);
+
+ Y = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) );
+ F = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) +2);
+ H = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(gbeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(gbeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(gbeps,Fp));
+ vgb = _mm_mul_pd(gbqqfactor,VV);
+
+ FF = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fgb = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
+ dvdatmp = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+ dvdasum = _mm_add_pd(dvdasum,dvdatmp);
+ gmx_mm_increment_2real_swizzle_pd(dvda+jnrA,dvda+jnrB,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(velec,rinv00),fgb),rinv00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vgbsum = _mm_add_pd(vgbsum,vgb);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 58 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ isaj0 = _mm_load_sd(invsqrta+jnrA+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* GENERALIZED BORN AND COULOMB ELECTROSTATICS */
+ isaprod = _mm_mul_pd(isai0,isaj0);
+ gbqqfactor = _mm_xor_pd(signbit,_mm_mul_pd(qq00,_mm_mul_pd(isaprod,gbinvepsdiff)));
+ gbscale = _mm_mul_pd(isaprod,gbtabscale);
+
+ /* Calculate generalized born table index - this is a separate table from the normal one,
+ * but we use the same procedure by multiplying r with scale and truncating to integer.
+ */
+ rt = _mm_mul_pd(r00,gbscale);
+ gbitab = _mm_cvttpd_epi32(rt);
+ gbeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(gbitab));
+ gbitab = _mm_slli_epi32(gbitab,2);
+
+ Y = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(gbeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(gbeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(gbeps,Fp));
+ vgb = _mm_mul_pd(gbqqfactor,VV);
+
+ FF = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fgb = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
+ dvdatmp = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+ dvdasum = _mm_add_pd(dvdasum,dvdatmp);
+ gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(velec,rinv00),fgb),rinv00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vgb = _mm_unpacklo_pd(vgb,_mm_setzero_pd());
+ vgbsum = _mm_add_pd(vgbsum,vgb);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 58 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vgbsum,kernel_data->energygrp_polarization+ggid);
+ dvdasum = _mm_mul_pd(dvdasum, _mm_mul_pd(isai0,isai0));
+ gmx_mm_update_1pot_pd(dvdasum,dvda+inr);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 9 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VF,outeriter*9 + inneriter*58);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecGB_VdwNone_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: GeneralizedBorn
+ * VdW interaction: None
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecGB_VdwNone_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128i gbitab;
+ __m128d vgb,fgb,vgbsum,dvdasum,gbscale,gbtabscale,isaprod,gbqqfactor,gbinvepsdiff,dvdaj,gbeps,dvdatmp;
+ __m128d minushalf = _mm_set1_pd(-0.5);
+ real *invsqrta,*dvda,*gbtab;
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+
+ invsqrta = fr->invsqrta;
+ dvda = fr->dvda;
+ gbtabscale = _mm_set1_pd(fr->gbtab.scale);
+ gbtab = fr->gbtab.data;
+ gbinvepsdiff = _mm_set1_pd((1.0/fr->epsilon_r) - (1.0/fr->gb_epsilon_solvent));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ isai0 = _mm_load1_pd(invsqrta+inr+0);
+
+ dvdasum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ isaj0 = gmx_mm_load_2real_swizzle_pd(invsqrta+jnrA+0,invsqrta+jnrB+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* GENERALIZED BORN AND COULOMB ELECTROSTATICS */
+ isaprod = _mm_mul_pd(isai0,isaj0);
+ gbqqfactor = _mm_xor_pd(signbit,_mm_mul_pd(qq00,_mm_mul_pd(isaprod,gbinvepsdiff)));
+ gbscale = _mm_mul_pd(isaprod,gbtabscale);
+
+ /* Calculate generalized born table index - this is a separate table from the normal one,
+ * but we use the same procedure by multiplying r with scale and truncating to integer.
+ */
+ rt = _mm_mul_pd(r00,gbscale);
+ gbitab = _mm_cvttpd_epi32(rt);
+ gbeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(gbitab));
+ gbitab = _mm_slli_epi32(gbitab,2);
+
+ Y = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) );
+ F = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) +2);
+ H = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(gbeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(gbeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(gbeps,Fp));
+ vgb = _mm_mul_pd(gbqqfactor,VV);
+
+ FF = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fgb = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
+ dvdatmp = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+ dvdasum = _mm_add_pd(dvdasum,dvdatmp);
+ gmx_mm_increment_2real_swizzle_pd(dvda+jnrA,dvda+jnrB,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(velec,rinv00),fgb),rinv00);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 56 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ isaj0 = _mm_load_sd(invsqrta+jnrA+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* GENERALIZED BORN AND COULOMB ELECTROSTATICS */
+ isaprod = _mm_mul_pd(isai0,isaj0);
+ gbqqfactor = _mm_xor_pd(signbit,_mm_mul_pd(qq00,_mm_mul_pd(isaprod,gbinvepsdiff)));
+ gbscale = _mm_mul_pd(isaprod,gbtabscale);
+
+ /* Calculate generalized born table index - this is a separate table from the normal one,
+ * but we use the same procedure by multiplying r with scale and truncating to integer.
+ */
+ rt = _mm_mul_pd(r00,gbscale);
+ gbitab = _mm_cvttpd_epi32(rt);
+ gbeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(gbitab));
+ gbitab = _mm_slli_epi32(gbitab,2);
+
+ Y = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(gbeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(gbeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(gbeps,Fp));
+ vgb = _mm_mul_pd(gbqqfactor,VV);
+
+ FF = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fgb = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
+ dvdatmp = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+ dvdasum = _mm_add_pd(dvdasum,dvdatmp);
+ gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
+ velec = _mm_mul_pd(qq00,rinv00);
+ felec = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(velec,rinv00),fgb),rinv00);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 56 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ dvdasum = _mm_mul_pd(dvdasum, _mm_mul_pd(isai0,isai0));
+ gmx_mm_update_1pot_pd(dvdasum,dvda+inr);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_F,outeriter*7 + inneriter*56);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecNone_VdwCSTab_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: None
+ * VdW interaction: CubicSplineTable
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecNone_VdwCSTab_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 56 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 56 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_VDW_VF,outeriter*7 + inneriter*56);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecNone_VdwCSTab_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: None
+ * VdW interaction: CubicSplineTable
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecNone_VdwCSTab_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 48 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ /* Load parameters for j particles */
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 48 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 6 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_VDW_F,outeriter*6 + inneriter*48);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecNone_VdwLJSh_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: None
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecNone_VdwLJSh_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ rcutoff_scalar = fr->rvdw;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+
+ /* Load parameters for j particles */
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 41 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+
+ /* Load parameters for j particles */
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 41 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_VDW_VF,outeriter*7 + inneriter*41);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecNone_VdwLJSh_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: None
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecNone_VdwLJSh_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ rcutoff_scalar = fr->rvdw;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+
+ /* Load parameters for j particles */
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 30 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+
+ /* Load parameters for j particles */
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 30 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 6 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_VDW_F,outeriter*6 + inneriter*30);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecNone_VdwLJSw_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: None
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecNone_VdwLJSw_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ rcutoff_scalar = fr->rvdw;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rvdw_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 59 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 59 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_VDW_VF,outeriter*7 + inneriter*59);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecNone_VdwLJSw_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: None
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecNone_VdwLJSw_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ rcutoff_scalar = fr->rvdw;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rvdw_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 56 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 56 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 6 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_VDW_F,outeriter*6 + inneriter*56);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecNone_VdwLJ_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: None
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecNone_VdwLJ_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+
+ /* Load parameters for j particles */
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 32 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+
+ /* Load parameters for j particles */
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 32 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_VDW_VF,outeriter*7 + inneriter*32);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecNone_VdwLJ_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: None
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecNone_VdwLJ_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+
+ /* Load parameters for j particles */
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 27 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+
+ /* Load parameters for j particles */
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 27 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 6 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_VDW_F,outeriter*6 + inneriter*27);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwCSTab_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwCSTab_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 72 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 72 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 9 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_VF,outeriter*9 + inneriter*72);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwCSTab_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwCSTab_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 57 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 57 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_F,outeriter*7 + inneriter*57);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwCSTab_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwCSTab_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 147 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 147 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_VF,outeriter*20 + inneriter*147);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwCSTab_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwCSTab_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 120 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 120 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_F,outeriter*18 + inneriter*120);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwCSTab_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwCSTab_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_add_pd(rinv01,_mm_mul_pd(krf,rsq01)),crf));
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_add_pd(rinv02,_mm_mul_pd(krf,rsq02)),crf));
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 360 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_add_pd(rinv01,_mm_mul_pd(krf,rsq01)),crf));
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_add_pd(rinv02,_mm_mul_pd(krf,rsq02)),crf));
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 360 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_VF,outeriter*20 + inneriter*360);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwCSTab_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwCSTab_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 297 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 297 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_F,outeriter*18 + inneriter*297);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwCSTab_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwCSTab_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_add_pd(rinv30,_mm_mul_pd(krf,rsq30)),crf));
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 167 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_add_pd(rinv30,_mm_mul_pd(krf,rsq30)),crf));
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 167 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_VF,outeriter*26 + inneriter*167);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwCSTab_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwCSTab_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 141 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 141 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_F,outeriter*24 + inneriter*141);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwCSTab_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwCSTab_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_add_pd(rinv13,_mm_mul_pd(krf,rsq13)),crf));
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_add_pd(rinv23,_mm_mul_pd(krf,rsq23)),crf));
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_add_pd(rinv31,_mm_mul_pd(krf,rsq31)),crf));
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_add_pd(rinv32,_mm_mul_pd(krf,rsq32)),crf));
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_add_pd(rinv33,_mm_mul_pd(krf,rsq33)),crf));
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 383 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_add_pd(rinv13,_mm_mul_pd(krf,rsq13)),crf));
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_add_pd(rinv23,_mm_mul_pd(krf,rsq23)),crf));
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_add_pd(rinv31,_mm_mul_pd(krf,rsq31)),crf));
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_add_pd(rinv32,_mm_mul_pd(krf,rsq32)),crf));
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_add_pd(rinv33,_mm_mul_pd(krf,rsq33)),crf));
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 383 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_VF,outeriter*26 + inneriter*383);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwCSTab_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwCSTab_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 321 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 321 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_F,outeriter*24 + inneriter*321);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSh_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSh_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 54 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 54 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 9 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_VF,outeriter*9 + inneriter*54);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSh_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSh_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 37 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 37 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_F,outeriter*7 + inneriter*37);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSh_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSh_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 129 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 129 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_VF,outeriter*20 + inneriter*129);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSh_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSh_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 100 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 100 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_F,outeriter*18 + inneriter*100);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSh_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSh_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_add_pd(rinv01,_mm_mul_pd(krf,rsq01)),crf));
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_add_pd(rinv02,_mm_mul_pd(krf,rsq02)),crf));
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 342 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_add_pd(rinv01,_mm_mul_pd(krf,rsq01)),crf));
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_add_pd(rinv02,_mm_mul_pd(krf,rsq02)),crf));
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 342 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_VF,outeriter*20 + inneriter*342);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSh_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSh_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 277 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 277 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_F,outeriter*18 + inneriter*277);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSh_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSh_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_add_pd(rinv30,_mm_mul_pd(krf,rsq30)),crf));
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 152 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_add_pd(rinv30,_mm_mul_pd(krf,rsq30)),crf));
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 152 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_VF,outeriter*26 + inneriter*152);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSh_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSh_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 123 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 123 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_F,outeriter*24 + inneriter*123);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSh_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSh_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_add_pd(rinv13,_mm_mul_pd(krf,rsq13)),crf));
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_add_pd(rinv23,_mm_mul_pd(krf,rsq23)),crf));
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_add_pd(rinv31,_mm_mul_pd(krf,rsq31)),crf));
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_add_pd(rinv32,_mm_mul_pd(krf,rsq32)),crf));
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_add_pd(rinv33,_mm_mul_pd(krf,rsq33)),crf));
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 368 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_00,sh_vdw_invrcut6)),one_sixth));
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_add_pd(rinv13,_mm_mul_pd(krf,rsq13)),crf));
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_add_pd(rinv23,_mm_mul_pd(krf,rsq23)),crf));
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_add_pd(rinv31,_mm_mul_pd(krf,rsq31)),crf));
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_add_pd(rinv32,_mm_mul_pd(krf,rsq32)),crf));
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_add_pd(rinv33,_mm_mul_pd(krf,rsq33)),crf));
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 368 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_VF,outeriter*26 + inneriter*368);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSh_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSh_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 303 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 303 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_F,outeriter*24 + inneriter*303);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSw_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSw_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rvdw_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 70 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 70 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 9 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_VF,outeriter*9 + inneriter*70);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSw_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSw_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rvdw_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 61 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 61 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_F,outeriter*7 + inneriter*61);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSw_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSw_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rvdw_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 145 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 145 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_VF,outeriter*20 + inneriter*145);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSw_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSw_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rvdw_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 124 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 124 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_F,outeriter*18 + inneriter*124);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSw_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSw_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rvdw_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_add_pd(rinv01,_mm_mul_pd(krf,rsq01)),crf));
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_add_pd(rinv02,_mm_mul_pd(krf,rsq02)),crf));
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 358 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_add_pd(rinv01,_mm_mul_pd(krf,rsq01)),crf));
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_add_pd(rinv02,_mm_mul_pd(krf,rsq02)),crf));
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 358 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_VF,outeriter*20 + inneriter*358);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSw_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSw_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rvdw_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 301 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 301 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_F,outeriter*18 + inneriter*301);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSw_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSw_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rvdw_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_add_pd(rinv30,_mm_mul_pd(krf,rsq30)),crf));
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 170 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_add_pd(rinv30,_mm_mul_pd(krf,rsq30)),crf));
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 170 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_VF,outeriter*26 + inneriter*170);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSw_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSw_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rvdw_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 149 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 149 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_F,outeriter*24 + inneriter*149);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSw_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSw_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rvdw_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_add_pd(rinv13,_mm_mul_pd(krf,rsq13)),crf));
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_add_pd(rinv23,_mm_mul_pd(krf,rsq23)),crf));
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_add_pd(rinv31,_mm_mul_pd(krf,rsq31)),crf));
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_add_pd(rinv32,_mm_mul_pd(krf,rsq32)),crf));
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_add_pd(rinv33,_mm_mul_pd(krf,rsq33)),crf));
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 386 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ vvdw = _mm_mul_pd(vvdw,sw);
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_add_pd(rinv13,_mm_mul_pd(krf,rsq13)),crf));
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_add_pd(rinv23,_mm_mul_pd(krf,rsq23)),crf));
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_add_pd(rinv31,_mm_mul_pd(krf,rsq31)),crf));
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_add_pd(rinv32,_mm_mul_pd(krf,rsq32)),crf));
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_add_pd(rinv33,_mm_mul_pd(krf,rsq33)),crf));
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 386 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_VF,outeriter*26 + inneriter*386);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwLJSw_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwLJSw_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ rswitch_scalar = fr->rvdw_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 329 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ d = _mm_sub_pd(r00,rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+
+ /* Evaluate switch function */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv00,_mm_mul_pd(vvdw,dsw)) );
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = fvdw;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 329 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_F,outeriter*24 + inneriter*329);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwNone_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwNone_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 36 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 36 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 8 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VF,outeriter*8 + inneriter*36);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwNone_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwNone_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 30 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ }
+
+ /* Inner loop uses 30 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_F,outeriter*7 + inneriter*30);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwNone_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwNone_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3_VF,outeriter*19 + inneriter*111);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwNone_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwNone_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 93 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 93 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3_F,outeriter*18 + inneriter*93);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwNone_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwNone_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ qq00 = _mm_mul_pd(iq0,jq0);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_add_pd(rinv01,_mm_mul_pd(krf,rsq01)),crf));
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_add_pd(rinv02,_mm_mul_pd(krf,rsq02)),crf));
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 324 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_add_pd(rinv01,_mm_mul_pd(krf,rsq01)),crf));
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_add_pd(rinv02,_mm_mul_pd(krf,rsq02)),crf));
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 324 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3W3_VF,outeriter*19 + inneriter*324);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwNone_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwNone_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ qq00 = _mm_mul_pd(iq0,jq0);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 270 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq00,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq00,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq01,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq01,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq02,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq02,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 270 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3W3_F,outeriter*18 + inneriter*270);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwNone_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwNone_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_add_pd(rinv30,_mm_mul_pd(krf,rsq30)),crf));
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_add_pd(rinv30,_mm_mul_pd(krf,rsq30)),crf));
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4_VF,outeriter*19 + inneriter*111);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwNone_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwNone_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 93 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq10,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq10,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq20,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq20,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq30,rcutoff2))
+ {
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq30,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ }
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 93 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4_F,outeriter*18 + inneriter*93);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwNone_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRFCut_VdwNone_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA+DIM,x+j_coord_offsetB+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_add_pd(rinv13,_mm_mul_pd(krf,rsq13)),crf));
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_add_pd(rinv23,_mm_mul_pd(krf,rsq23)),crf));
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_add_pd(rinv31,_mm_mul_pd(krf,rsq31)),crf));
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_add_pd(rinv32,_mm_mul_pd(krf,rsq32)),crf));
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_add_pd(rinv33,_mm_mul_pd(krf,rsq33)),crf));
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA+DIM,f+j_coord_offsetB+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 324 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_add_pd(rinv13,_mm_mul_pd(krf,rsq13)),crf));
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_add_pd(rinv23,_mm_mul_pd(krf,rsq23)),crf));
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_add_pd(rinv31,_mm_mul_pd(krf,rsq31)),crf));
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_add_pd(rinv32,_mm_mul_pd(krf,rsq32)),crf));
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_add_pd(rinv33,_mm_mul_pd(krf,rsq33)),crf));
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 324 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4W4_VF,outeriter*19 + inneriter*324);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRFCut_VdwNone_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRFCut_VdwNone_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA+DIM,x+j_coord_offsetB+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA+DIM,f+j_coord_offsetB+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 270 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq11,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq11,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq12,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq12,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq13,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq13,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq21,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq21,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq22,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq22,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq23,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq23,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq31,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq31,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq32,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq32,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ }
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ if (gmx_mm_any_lt(rsq33,rcutoff2))
+ {
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ cutoff_mask = _mm_cmplt_pd(rsq33,rcutoff2);
+
+ fscal = felec;
+
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ }
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 270 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4W4_F,outeriter*18 + inneriter*270);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwCSTab_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRF_VdwCSTab_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 67 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 67 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 9 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_VF,outeriter*9 + inneriter*67);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwCSTab_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRF_VdwCSTab_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 54 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 54 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_F,outeriter*7 + inneriter*54);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwCSTab_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRF_VdwCSTab_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 134 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 134 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_VF,outeriter*20 + inneriter*134);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwCSTab_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRF_VdwCSTab_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_F,outeriter*18 + inneriter*111);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwCSTab_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRF_VdwCSTab_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_add_pd(rinv01,_mm_mul_pd(krf,rsq01)),crf));
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_add_pd(rinv02,_mm_mul_pd(krf,rsq02)),crf));
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 323 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_add_pd(rinv01,_mm_mul_pd(krf,rsq01)),crf));
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_add_pd(rinv02,_mm_mul_pd(krf,rsq02)),crf));
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 323 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_VF,outeriter*20 + inneriter*323);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwCSTab_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRF_VdwCSTab_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 270 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 270 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_F,outeriter*18 + inneriter*270);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwCSTab_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRF_VdwCSTab_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_add_pd(rinv30,_mm_mul_pd(krf,rsq30)),crf));
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 155 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_add_pd(rinv30,_mm_mul_pd(krf,rsq30)),crf));
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 155 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_VF,outeriter*26 + inneriter*155);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwCSTab_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRF_VdwCSTab_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 132 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 132 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_F,outeriter*24 + inneriter*132);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwCSTab_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRF_VdwCSTab_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_add_pd(rinv13,_mm_mul_pd(krf,rsq13)),crf));
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_add_pd(rinv23,_mm_mul_pd(krf,rsq23)),crf));
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_add_pd(rinv31,_mm_mul_pd(krf,rsq31)),crf));
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_add_pd(rinv32,_mm_mul_pd(krf,rsq32)),crf));
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_add_pd(rinv33,_mm_mul_pd(krf,rsq33)),crf));
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 347 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_00,VV);
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_add_pd(rinv13,_mm_mul_pd(krf,rsq13)),crf));
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_add_pd(rinv23,_mm_mul_pd(krf,rsq23)),crf));
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_add_pd(rinv31,_mm_mul_pd(krf,rsq31)),crf));
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_add_pd(rinv32,_mm_mul_pd(krf,rsq32)),crf));
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_add_pd(rinv33,_mm_mul_pd(krf,rsq33)),crf));
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 347 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_VF,outeriter*26 + inneriter*347);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwCSTab_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: CubicSplineTable
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRF_VdwCSTab_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 294 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ r00 = _mm_mul_pd(rsq00,rinv00);
+
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r00,vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ vfitab = _mm_slli_epi32(vfitab,3);
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_00,FF);
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ F = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ H = _mm_setzero_pd();
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_00,FF);
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 294 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_F,outeriter*24 + inneriter*294);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwLJ_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRF_VdwLJ_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 44 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 44 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 9 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_VF,outeriter*9 + inneriter*44);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwLJ_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRF_VdwLJ_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 34 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 34 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_F,outeriter*7 + inneriter*34);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwLJ_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRF_VdwLJ_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_VF,outeriter*20 + inneriter*111);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwLJ_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRF_VdwLJ_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 91 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 91 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3_F,outeriter*18 + inneriter*91);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwLJ_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRF_VdwLJ_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_add_pd(rinv01,_mm_mul_pd(krf,rsq01)),crf));
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_add_pd(rinv02,_mm_mul_pd(krf,rsq02)),crf));
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 300 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_add_pd(rinv01,_mm_mul_pd(krf,rsq01)),crf));
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_add_pd(rinv02,_mm_mul_pd(krf,rsq02)),crf));
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 300 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 20 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_VF,outeriter*20 + inneriter*300);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwLJ_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRF_VdwLJ_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ qq00 = _mm_mul_pd(iq0,jq0);
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 250 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = _mm_add_pd(felec,fvdw);
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 250 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_F,outeriter*18 + inneriter*250);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwLJ_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRF_VdwLJ_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_add_pd(rinv30,_mm_mul_pd(krf,rsq30)),crf));
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 131 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_add_pd(rinv30,_mm_mul_pd(krf,rsq30)),crf));
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 131 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_VF,outeriter*26 + inneriter*131);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwLJ_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRF_VdwLJ_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+ vdwjidx0B = 2*vdwtype[jnrB+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,
+ vdwparam+vdwioffset0+vdwjidx0B,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+ vdwjidx0A = 2*vdwtype[jnrA+0];
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset0+vdwjidx0A,&c6_00,&c12_00);
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 111 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_F,outeriter*24 + inneriter*111);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwLJ_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRF_VdwLJ_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+ vvdwsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_add_pd(rinv13,_mm_mul_pd(krf,rsq13)),crf));
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_add_pd(rinv23,_mm_mul_pd(krf,rsq23)),crf));
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_add_pd(rinv31,_mm_mul_pd(krf,rsq31)),crf));
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_add_pd(rinv32,_mm_mul_pd(krf,rsq32)),crf));
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_add_pd(rinv33,_mm_mul_pd(krf,rsq33)),crf));
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 323 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ vvdw6 = _mm_mul_pd(c6_00,rinvsix);
+ vvdw12 = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq00);
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_add_pd(rinv13,_mm_mul_pd(krf,rsq13)),crf));
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_add_pd(rinv23,_mm_mul_pd(krf,rsq23)),crf));
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_add_pd(rinv31,_mm_mul_pd(krf,rsq31)),crf));
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_add_pd(rinv32,_mm_mul_pd(krf,rsq32)),crf));
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_add_pd(rinv33,_mm_mul_pd(krf,rsq33)),crf));
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 323 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 26 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_VF,outeriter*26 + inneriter*323);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwLJ_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: LennardJones
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRF_VdwLJ_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+ vdwioffset0 = 2*nvdwtype*vdwtype[inr+0];
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ vdwjidx0A = 2*vdwtype[inr+0];
+ c6_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
+ c12_00 = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 273 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq00 = gmx_mm_inv_pd(rsq00);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_00,rinvsix),c6_00),_mm_mul_pd(rinvsix,rinvsq00));
+
+ fscal = fvdw;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 273 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 24 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_F,outeriter*24 + inneriter*273);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwNone_GeomP1P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Particle-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRF_VdwNone_GeomP1P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 32 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 32 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 8 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VF,outeriter*8 + inneriter*32);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwNone_GeomP1P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Particle-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRF_VdwNone_GeomP1P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+
+ /* Load parameters for i particles */
+ iq0 = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+0));
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+
+ /* Inner loop uses 27 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+
+ /* Inner loop uses 27 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 7 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_F,outeriter*7 + inneriter*27);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwNone_GeomW3P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Water3-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRF_VdwNone_GeomW3P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 99 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 99 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3_VF,outeriter*19 + inneriter*99);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwNone_GeomW3P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Water3-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRF_VdwNone_GeomW3P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 84 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq00 = _mm_mul_pd(iq0,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 84 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3_F,outeriter*18 + inneriter*84);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwNone_GeomW3W3_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Water3-Water3
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRF_VdwNone_GeomW3W3_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ qq00 = _mm_mul_pd(iq0,jq0);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_add_pd(rinv01,_mm_mul_pd(krf,rsq01)),crf));
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_add_pd(rinv02,_mm_mul_pd(krf,rsq02)),crf));
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 288 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_add_pd(rinv01,_mm_mul_pd(krf,rsq01)),crf));
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_add_pd(rinv02,_mm_mul_pd(krf,rsq02)),crf));
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 288 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3W3_VF,outeriter*19 + inneriter*288);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwNone_GeomW3W3_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Water3-Water3
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRF_VdwNone_GeomW3W3_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset0;
+ __m128d ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ __m128d dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
+ __m128d dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
+ __m128d dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq0 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+
+ jq0 = _mm_set1_pd(charge[inr+0]);
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ qq00 = _mm_mul_pd(iq0,jq0);
+ qq01 = _mm_mul_pd(iq0,jq1);
+ qq02 = _mm_mul_pd(iq0,jq2);
+ qq10 = _mm_mul_pd(iq1,jq0);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq20 = _mm_mul_pd(iq2,jq0);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+
+ fix0 = _mm_setzero_pd();
+ fiy0 = _mm_setzero_pd();
+ fiz0 = _mm_setzero_pd();
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 243 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+
+ /* Calculate displacement vector */
+ dx00 = _mm_sub_pd(ix0,jx0);
+ dy00 = _mm_sub_pd(iy0,jy0);
+ dz00 = _mm_sub_pd(iz0,jz0);
+ dx01 = _mm_sub_pd(ix0,jx1);
+ dy01 = _mm_sub_pd(iy0,jy1);
+ dz01 = _mm_sub_pd(iz0,jz1);
+ dx02 = _mm_sub_pd(ix0,jx2);
+ dy02 = _mm_sub_pd(iy0,jy2);
+ dz02 = _mm_sub_pd(iz0,jz2);
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+
+ /* Calculate squared distance and things based on it */
+ rsq00 = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
+ rsq01 = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
+ rsq02 = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+
+ rinv00 = gmx_mm_invsqrt_pd(rsq00);
+ rinv01 = gmx_mm_invsqrt_pd(rsq01);
+ rinv02 = gmx_mm_invsqrt_pd(rsq02);
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+
+ rinvsq00 = _mm_mul_pd(rinv00,rinv00);
+ rinvsq01 = _mm_mul_pd(rinv01,rinv01);
+ rinvsq02 = _mm_mul_pd(rinv02,rinv02);
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx00);
+ ty = _mm_mul_pd(fscal,dy00);
+ tz = _mm_mul_pd(fscal,dz00);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx01);
+ ty = _mm_mul_pd(fscal,dy01);
+ tz = _mm_mul_pd(fscal,dz01);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx02);
+ ty = _mm_mul_pd(fscal,dy02);
+ tz = _mm_mul_pd(fscal,dz02);
+
+ /* Update vectorial force */
+ fix0 = _mm_add_pd(fix0,tx);
+ fiy0 = _mm_add_pd(fiy0,ty);
+ fiz0 = _mm_add_pd(fiz0,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+
+ /* Inner loop uses 243 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W3W3_F,outeriter*18 + inneriter*243);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwNone_GeomW4P1_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Water4-Particle
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRF_VdwNone_GeomW4P1_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_add_pd(rinv30,_mm_mul_pd(krf,rsq30)),crf));
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 99 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_add_pd(rinv30,_mm_mul_pd(krf,rsq30)),crf));
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 99 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4_VF,outeriter*19 + inneriter*99);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwNone_GeomW4P1_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Water4-Particle
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRF_VdwNone_GeomW4P1_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx0A,vdwjidx0B;
+ __m128d jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
+ __m128d dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
+ __m128d dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
+ __m128d dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = gmx_mm_load_2real_swizzle_pd(charge+jnrA+0,charge+jnrB+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 84 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+
+ /* Calculate displacement vector */
+ dx10 = _mm_sub_pd(ix1,jx0);
+ dy10 = _mm_sub_pd(iy1,jy0);
+ dz10 = _mm_sub_pd(iz1,jz0);
+ dx20 = _mm_sub_pd(ix2,jx0);
+ dy20 = _mm_sub_pd(iy2,jy0);
+ dz20 = _mm_sub_pd(iz2,jz0);
+ dx30 = _mm_sub_pd(ix3,jx0);
+ dy30 = _mm_sub_pd(iy3,jy0);
+ dz30 = _mm_sub_pd(iz3,jz0);
+
+ /* Calculate squared distance and things based on it */
+ rsq10 = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
+ rsq20 = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
+ rsq30 = gmx_mm_calc_rsq_pd(dx30,dy30,dz30);
+
+ rinv10 = gmx_mm_invsqrt_pd(rsq10);
+ rinv20 = gmx_mm_invsqrt_pd(rsq20);
+ rinv30 = gmx_mm_invsqrt_pd(rsq30);
+
+ rinvsq10 = _mm_mul_pd(rinv10,rinv10);
+ rinvsq20 = _mm_mul_pd(rinv20,rinv20);
+ rinvsq30 = _mm_mul_pd(rinv30,rinv30);
+
+ /* Load parameters for j particles */
+ jq0 = _mm_load_sd(charge+jnrA+0);
+
+ fjx0 = _mm_setzero_pd();
+ fjy0 = _mm_setzero_pd();
+ fjz0 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq10 = _mm_mul_pd(iq1,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx10);
+ ty = _mm_mul_pd(fscal,dy10);
+ tz = _mm_mul_pd(fscal,dz10);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq20 = _mm_mul_pd(iq2,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx20);
+ ty = _mm_mul_pd(fscal,dy20);
+ tz = _mm_mul_pd(fscal,dz20);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* Compute parameters for interactions between i and j atoms */
+ qq30 = _mm_mul_pd(iq3,jq0);
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq30,_mm_sub_pd(_mm_mul_pd(rinv30,rinvsq30),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx30);
+ ty = _mm_mul_pd(fscal,dy30);
+ tz = _mm_mul_pd(fscal,dz30);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx0 = _mm_add_pd(fjx0,tx);
+ fjy0 = _mm_add_pd(fjy0,ty);
+ fjz0 = _mm_add_pd(fjz0,tz);
+
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+
+ /* Inner loop uses 84 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4_F,outeriter*18 + inneriter*84);
+}
--- /dev/null
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwNone_GeomW4W4_VF_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Water4-Water4
+ * Calculate force/pot: PotentialAndForce
+ */
+void
+nb_kernel_ElecRF_VdwNone_GeomW4W4_VF_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Reset potential sums */
+ velecsum = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA+DIM,x+j_coord_offsetB+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_add_pd(rinv13,_mm_mul_pd(krf,rsq13)),crf));
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_add_pd(rinv23,_mm_mul_pd(krf,rsq23)),crf));
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_add_pd(rinv31,_mm_mul_pd(krf,rsq31)),crf));
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_add_pd(rinv32,_mm_mul_pd(krf,rsq32)),crf));
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_add_pd(rinv33,_mm_mul_pd(krf,rsq33)),crf));
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA+DIM,f+j_coord_offsetB+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 288 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_add_pd(rinv13,_mm_mul_pd(krf,rsq13)),crf));
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_add_pd(rinv23,_mm_mul_pd(krf,rsq23)),crf));
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_add_pd(rinv31,_mm_mul_pd(krf,rsq31)),crf));
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_add_pd(rinv32,_mm_mul_pd(krf,rsq32)),crf));
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ velec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_add_pd(rinv33,_mm_mul_pd(krf,rsq33)),crf));
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ velecsum = _mm_add_pd(velecsum,velec);
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 288 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ ggid = gid[iidx];
+ /* Update potential energies */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 19 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4W4_VF,outeriter*19 + inneriter*288);
+}
+/*
+ * Gromacs nonbonded kernel: nb_kernel_ElecRF_VdwNone_GeomW4W4_F_sse2_double
+ * Electrostatics interaction: ReactionField
+ * VdW interaction: None
+ * Geometry: Water4-Water4
+ * Calculate force/pot: Force
+ */
+void
+nb_kernel_ElecRF_VdwNone_GeomW4W4_F_sse2_double
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ int vdwioffset1;
+ __m128d ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
+ int vdwioffset2;
+ __m128d ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
+ int vdwioffset3;
+ __m128d ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
+ int vdwjidx1A,vdwjidx1B;
+ __m128d jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
+ int vdwjidx2A,vdwjidx2B;
+ __m128d jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
+ int vdwjidx3A,vdwjidx3B;
+ __m128d jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
+ __m128d dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
+ __m128d dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
+ __m128d dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
+ __m128d dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
+ __m128d dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
+ __m128d dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
+ __m128d dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
+ __m128d dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
+ __m128d dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ iq1 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
+ iq2 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
+ iq3 = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+3]));
+
+ jq1 = _mm_set1_pd(charge[inr+1]);
+ jq2 = _mm_set1_pd(charge[inr+2]);
+ jq3 = _mm_set1_pd(charge[inr+3]);
+ qq11 = _mm_mul_pd(iq1,jq1);
+ qq12 = _mm_mul_pd(iq1,jq2);
+ qq13 = _mm_mul_pd(iq1,jq3);
+ qq21 = _mm_mul_pd(iq2,jq1);
+ qq22 = _mm_mul_pd(iq2,jq2);
+ qq23 = _mm_mul_pd(iq2,jq3);
+ qq31 = _mm_mul_pd(iq3,jq1);
+ qq32 = _mm_mul_pd(iq3,jq2);
+ qq33 = _mm_mul_pd(iq3,jq3);
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+
+ fix1 = _mm_setzero_pd();
+ fiy1 = _mm_setzero_pd();
+ fiz1 = _mm_setzero_pd();
+ fix2 = _mm_setzero_pd();
+ fiy2 = _mm_setzero_pd();
+ fiz2 = _mm_setzero_pd();
+ fix3 = _mm_setzero_pd();
+ fiy3 = _mm_setzero_pd();
+ fiz3 = _mm_setzero_pd();
+
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA+DIM,x+j_coord_offsetB+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ fscal = felec;
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA+DIM,f+j_coord_offsetB+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 243 flops */
+ }
+
+ if(jidx<j_index_end)
+ {
+
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+
+ /* Calculate displacement vector */
+ dx11 = _mm_sub_pd(ix1,jx1);
+ dy11 = _mm_sub_pd(iy1,jy1);
+ dz11 = _mm_sub_pd(iz1,jz1);
+ dx12 = _mm_sub_pd(ix1,jx2);
+ dy12 = _mm_sub_pd(iy1,jy2);
+ dz12 = _mm_sub_pd(iz1,jz2);
+ dx13 = _mm_sub_pd(ix1,jx3);
+ dy13 = _mm_sub_pd(iy1,jy3);
+ dz13 = _mm_sub_pd(iz1,jz3);
+ dx21 = _mm_sub_pd(ix2,jx1);
+ dy21 = _mm_sub_pd(iy2,jy1);
+ dz21 = _mm_sub_pd(iz2,jz1);
+ dx22 = _mm_sub_pd(ix2,jx2);
+ dy22 = _mm_sub_pd(iy2,jy2);
+ dz22 = _mm_sub_pd(iz2,jz2);
+ dx23 = _mm_sub_pd(ix2,jx3);
+ dy23 = _mm_sub_pd(iy2,jy3);
+ dz23 = _mm_sub_pd(iz2,jz3);
+ dx31 = _mm_sub_pd(ix3,jx1);
+ dy31 = _mm_sub_pd(iy3,jy1);
+ dz31 = _mm_sub_pd(iz3,jz1);
+ dx32 = _mm_sub_pd(ix3,jx2);
+ dy32 = _mm_sub_pd(iy3,jy2);
+ dz32 = _mm_sub_pd(iz3,jz2);
+ dx33 = _mm_sub_pd(ix3,jx3);
+ dy33 = _mm_sub_pd(iy3,jy3);
+ dz33 = _mm_sub_pd(iz3,jz3);
+
+ /* Calculate squared distance and things based on it */
+ rsq11 = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
+ rsq12 = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
+ rsq13 = gmx_mm_calc_rsq_pd(dx13,dy13,dz13);
+ rsq21 = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
+ rsq22 = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
+ rsq23 = gmx_mm_calc_rsq_pd(dx23,dy23,dz23);
+ rsq31 = gmx_mm_calc_rsq_pd(dx31,dy31,dz31);
+ rsq32 = gmx_mm_calc_rsq_pd(dx32,dy32,dz32);
+ rsq33 = gmx_mm_calc_rsq_pd(dx33,dy33,dz33);
+
+ rinv11 = gmx_mm_invsqrt_pd(rsq11);
+ rinv12 = gmx_mm_invsqrt_pd(rsq12);
+ rinv13 = gmx_mm_invsqrt_pd(rsq13);
+ rinv21 = gmx_mm_invsqrt_pd(rsq21);
+ rinv22 = gmx_mm_invsqrt_pd(rsq22);
+ rinv23 = gmx_mm_invsqrt_pd(rsq23);
+ rinv31 = gmx_mm_invsqrt_pd(rsq31);
+ rinv32 = gmx_mm_invsqrt_pd(rsq32);
+ rinv33 = gmx_mm_invsqrt_pd(rsq33);
+
+ rinvsq11 = _mm_mul_pd(rinv11,rinv11);
+ rinvsq12 = _mm_mul_pd(rinv12,rinv12);
+ rinvsq13 = _mm_mul_pd(rinv13,rinv13);
+ rinvsq21 = _mm_mul_pd(rinv21,rinv21);
+ rinvsq22 = _mm_mul_pd(rinv22,rinv22);
+ rinvsq23 = _mm_mul_pd(rinv23,rinv23);
+ rinvsq31 = _mm_mul_pd(rinv31,rinv31);
+ rinvsq32 = _mm_mul_pd(rinv32,rinv32);
+ rinvsq33 = _mm_mul_pd(rinv33,rinv33);
+
+ fjx1 = _mm_setzero_pd();
+ fjy1 = _mm_setzero_pd();
+ fjz1 = _mm_setzero_pd();
+ fjx2 = _mm_setzero_pd();
+ fjy2 = _mm_setzero_pd();
+ fjz2 = _mm_setzero_pd();
+ fjx3 = _mm_setzero_pd();
+ fjy3 = _mm_setzero_pd();
+ fjz3 = _mm_setzero_pd();
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx11);
+ ty = _mm_mul_pd(fscal,dy11);
+ tz = _mm_mul_pd(fscal,dz11);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx12);
+ ty = _mm_mul_pd(fscal,dy12);
+ tz = _mm_mul_pd(fscal,dz12);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq13,_mm_sub_pd(_mm_mul_pd(rinv13,rinvsq13),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx13);
+ ty = _mm_mul_pd(fscal,dy13);
+ tz = _mm_mul_pd(fscal,dz13);
+
+ /* Update vectorial force */
+ fix1 = _mm_add_pd(fix1,tx);
+ fiy1 = _mm_add_pd(fiy1,ty);
+ fiz1 = _mm_add_pd(fiz1,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx21);
+ ty = _mm_mul_pd(fscal,dy21);
+ tz = _mm_mul_pd(fscal,dz21);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx22);
+ ty = _mm_mul_pd(fscal,dy22);
+ tz = _mm_mul_pd(fscal,dz22);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq23,_mm_sub_pd(_mm_mul_pd(rinv23,rinvsq23),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx23);
+ ty = _mm_mul_pd(fscal,dy23);
+ tz = _mm_mul_pd(fscal,dz23);
+
+ /* Update vectorial force */
+ fix2 = _mm_add_pd(fix2,tx);
+ fiy2 = _mm_add_pd(fiy2,ty);
+ fiz2 = _mm_add_pd(fiz2,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq31,_mm_sub_pd(_mm_mul_pd(rinv31,rinvsq31),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx31);
+ ty = _mm_mul_pd(fscal,dy31);
+ tz = _mm_mul_pd(fscal,dz31);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx1 = _mm_add_pd(fjx1,tx);
+ fjy1 = _mm_add_pd(fjy1,ty);
+ fjz1 = _mm_add_pd(fjz1,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq32,_mm_sub_pd(_mm_mul_pd(rinv32,rinvsq32),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx32);
+ ty = _mm_mul_pd(fscal,dy32);
+ tz = _mm_mul_pd(fscal,dz32);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx2 = _mm_add_pd(fjx2,tx);
+ fjy2 = _mm_add_pd(fjy2,ty);
+ fjz2 = _mm_add_pd(fjz2,tz);
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ felec = _mm_mul_pd(qq33,_mm_sub_pd(_mm_mul_pd(rinv33,rinvsq33),krf2));
+
+ fscal = felec;
+
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx33);
+ ty = _mm_mul_pd(fscal,dy33);
+ tz = _mm_mul_pd(fscal,dz33);
+
+ /* Update vectorial force */
+ fix3 = _mm_add_pd(fix3,tx);
+ fiy3 = _mm_add_pd(fiy3,ty);
+ fiz3 = _mm_add_pd(fiz3,tz);
+
+ fjx3 = _mm_add_pd(fjx3,tx);
+ fjy3 = _mm_add_pd(fjy3,ty);
+ fjz3 = _mm_add_pd(fjz3,tz);
+
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+
+ /* Inner loop uses 243 flops */
+ }
+
+ /* End of innermost loop */
+
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses 18 flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_W4W4_F,outeriter*18 + inneriter*243);
+}
-/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
+/*
+ * Note: this file was generated by the Gromacs sse2_double kernel generator.
*
- * This file is part of Gromacs Copyright (c) 1991-2004
- * David van der Spoel, Erik Lindahl, University of Groningen.
+ * This source code is part of
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * G R O M A C S
*
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org
- *
- * And Hey:
- * Gnomes, ROck Monsters And Chili Sauce
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-/* Must come directly after config.h */
-#ifdef GMX_THREAD_SHM_FDECOMP
-#include <thread_mpi.h>
-#endif
-
-#include <types/simple.h>
-#include <types/nrnb.h>
-
-#include "nb_kernel_sse2_double.h"
+#ifndef nb_kernel_sse2_double_h
+#define nb_kernel_sse2_double_h
-/* Include double precision SSE intrinsics kernel headers in local directory */
-#include "nb_kernel400_sse2_double.h"
-#include "nb_kernel410_sse2_double.h"
-#include "nb_kernel430_sse2_double.h"
+#include "../nb_kernel.h"
-#include <stdlib.h>
-#include <stdio.h>
+nb_kernel_t nb_kernel_ElecNone_VdwLJ_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecNone_VdwLJ_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecNone_VdwLJSh_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecNone_VdwLJSh_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecNone_VdwLJSw_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecNone_VdwLJSw_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecNone_VdwCSTab_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecNone_VdwCSTab_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwLJ_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwLJ_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwLJ_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwLJ_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwLJ_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwLJ_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwLJ_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwLJ_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwLJ_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwLJ_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwNone_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwNone_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwNone_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwNone_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwNone_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwNone_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwNone_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwNone_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwNone_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwNone_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwCSTab_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwCSTab_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwCSTab_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwCSTab_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwCSTab_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwCSTab_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwCSTab_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwCSTab_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwCSTab_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEw_VdwCSTab_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwLJSh_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwLJSh_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwLJSh_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwLJSh_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwLJSh_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwLJSh_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwLJSh_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwLJSh_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwLJSh_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwLJSh_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwNone_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwNone_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwNone_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwNone_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwNone_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwNone_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwNone_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwNone_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwNone_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSh_VdwNone_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwLJSw_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwLJSw_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwLJSw_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwLJSw_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwLJSw_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwLJSw_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwLJSw_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwLJSw_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwLJSw_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwLJSw_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwNone_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwNone_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwNone_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwNone_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwNone_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwNone_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwNone_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwNone_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwNone_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecEwSw_VdwNone_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwLJ_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwLJ_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwLJ_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwLJ_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwLJ_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwLJ_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwLJ_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwLJ_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwLJ_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwLJ_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwNone_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwNone_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwNone_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwNone_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwNone_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwNone_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwNone_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwNone_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwNone_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwNone_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwCSTab_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwCSTab_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwCSTab_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwCSTab_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwCSTab_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwCSTab_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwCSTab_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwCSTab_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwCSTab_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCoul_VdwCSTab_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwLJ_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwLJ_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwLJ_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwLJ_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwLJ_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwLJ_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwLJ_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwLJ_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwLJ_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwLJ_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwNone_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwNone_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwNone_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwNone_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwNone_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwNone_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwNone_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwNone_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwNone_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwNone_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwCSTab_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwCSTab_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwCSTab_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwCSTab_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwCSTab_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwCSTab_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwCSTab_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwCSTab_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwCSTab_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecCSTab_VdwCSTab_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecGB_VdwLJ_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecGB_VdwLJ_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecGB_VdwNone_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecGB_VdwNone_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecGB_VdwCSTab_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecGB_VdwCSTab_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSh_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSh_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSh_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSh_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSh_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSh_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSh_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSh_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSh_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSh_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSw_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSw_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSw_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSw_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSw_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSw_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSw_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSw_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSw_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwLJSw_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwNone_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwNone_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwNone_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwNone_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwNone_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwNone_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwNone_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwNone_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwNone_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwNone_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwCSTab_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwCSTab_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwCSTab_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwCSTab_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwCSTab_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwCSTab_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwCSTab_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwCSTab_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwCSTab_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRFCut_VdwCSTab_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwLJ_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwLJ_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwLJ_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwLJ_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwLJ_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwLJ_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwLJ_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwLJ_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwLJ_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwLJ_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwNone_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwNone_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwNone_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwNone_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwNone_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwNone_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwNone_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwNone_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwNone_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwNone_GeomW4W4_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwCSTab_GeomP1P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwCSTab_GeomP1P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwCSTab_GeomW3P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwCSTab_GeomW3P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwCSTab_GeomW3W3_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwCSTab_GeomW3W3_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwCSTab_GeomW4P1_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwCSTab_GeomW4P1_F_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwCSTab_GeomW4W4_VF_sse2_double;
+nb_kernel_t nb_kernel_ElecRF_VdwCSTab_GeomW4W4_F_sse2_double;
-#include "../nb_kernel.h"
-#include "nb_kernel_sse2_double.h"
-static nb_kernel_t *
-kernellist_sse2_double[eNR_NBKERNEL_NR] =
+nb_kernel_info_t
+kernellist_sse2_double[] =
{
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- nb_kernel400_sse2_double,
- nb_kernel410_sse2_double,
- nb_kernel430_sse2_double
+ { nb_kernel_ElecNone_VdwLJ_GeomP1P1_VF_sse2_double, "nb_kernel_ElecNone_VdwLJ_GeomP1P1_VF_sse2_double", "sse2_double", "None", "None", "LennardJones", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecNone_VdwLJ_GeomP1P1_F_sse2_double, "nb_kernel_ElecNone_VdwLJ_GeomP1P1_F_sse2_double", "sse2_double", "None", "None", "LennardJones", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecNone_VdwLJSh_GeomP1P1_VF_sse2_double, "nb_kernel_ElecNone_VdwLJSh_GeomP1P1_VF_sse2_double", "sse2_double", "None", "None", "LennardJones", "PotentialShift", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecNone_VdwLJSh_GeomP1P1_F_sse2_double, "nb_kernel_ElecNone_VdwLJSh_GeomP1P1_F_sse2_double", "sse2_double", "None", "None", "LennardJones", "PotentialShift", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecNone_VdwLJSw_GeomP1P1_VF_sse2_double, "nb_kernel_ElecNone_VdwLJSw_GeomP1P1_VF_sse2_double", "sse2_double", "None", "None", "LennardJones", "PotentialSwitch", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecNone_VdwLJSw_GeomP1P1_F_sse2_double, "nb_kernel_ElecNone_VdwLJSw_GeomP1P1_F_sse2_double", "sse2_double", "None", "None", "LennardJones", "PotentialSwitch", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecNone_VdwCSTab_GeomP1P1_VF_sse2_double, "nb_kernel_ElecNone_VdwCSTab_GeomP1P1_VF_sse2_double", "sse2_double", "None", "None", "CubicSplineTable", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecNone_VdwCSTab_GeomP1P1_F_sse2_double, "nb_kernel_ElecNone_VdwCSTab_GeomP1P1_F_sse2_double", "sse2_double", "None", "None", "CubicSplineTable", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecEw_VdwLJ_GeomP1P1_VF_sse2_double, "nb_kernel_ElecEw_VdwLJ_GeomP1P1_VF_sse2_double", "sse2_double", "Ewald", "None", "LennardJones", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEw_VdwLJ_GeomP1P1_F_sse2_double, "nb_kernel_ElecEw_VdwLJ_GeomP1P1_F_sse2_double", "sse2_double", "Ewald", "None", "LennardJones", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecEw_VdwLJ_GeomW3P1_VF_sse2_double, "nb_kernel_ElecEw_VdwLJ_GeomW3P1_VF_sse2_double", "sse2_double", "Ewald", "None", "LennardJones", "None", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEw_VdwLJ_GeomW3P1_F_sse2_double, "nb_kernel_ElecEw_VdwLJ_GeomW3P1_F_sse2_double", "sse2_double", "Ewald", "None", "LennardJones", "None", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecEw_VdwLJ_GeomW3W3_VF_sse2_double, "nb_kernel_ElecEw_VdwLJ_GeomW3W3_VF_sse2_double", "sse2_double", "Ewald", "None", "LennardJones", "None", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecEw_VdwLJ_GeomW3W3_F_sse2_double, "nb_kernel_ElecEw_VdwLJ_GeomW3W3_F_sse2_double", "sse2_double", "Ewald", "None", "LennardJones", "None", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecEw_VdwLJ_GeomW4P1_VF_sse2_double, "nb_kernel_ElecEw_VdwLJ_GeomW4P1_VF_sse2_double", "sse2_double", "Ewald", "None", "LennardJones", "None", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEw_VdwLJ_GeomW4P1_F_sse2_double, "nb_kernel_ElecEw_VdwLJ_GeomW4P1_F_sse2_double", "sse2_double", "Ewald", "None", "LennardJones", "None", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecEw_VdwLJ_GeomW4W4_VF_sse2_double, "nb_kernel_ElecEw_VdwLJ_GeomW4W4_VF_sse2_double", "sse2_double", "Ewald", "None", "LennardJones", "None", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecEw_VdwLJ_GeomW4W4_F_sse2_double, "nb_kernel_ElecEw_VdwLJ_GeomW4W4_F_sse2_double", "sse2_double", "Ewald", "None", "LennardJones", "None", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecEw_VdwNone_GeomP1P1_VF_sse2_double, "nb_kernel_ElecEw_VdwNone_GeomP1P1_VF_sse2_double", "sse2_double", "Ewald", "None", "None", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEw_VdwNone_GeomP1P1_F_sse2_double, "nb_kernel_ElecEw_VdwNone_GeomP1P1_F_sse2_double", "sse2_double", "Ewald", "None", "None", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecEw_VdwNone_GeomW3P1_VF_sse2_double, "nb_kernel_ElecEw_VdwNone_GeomW3P1_VF_sse2_double", "sse2_double", "Ewald", "None", "None", "None", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEw_VdwNone_GeomW3P1_F_sse2_double, "nb_kernel_ElecEw_VdwNone_GeomW3P1_F_sse2_double", "sse2_double", "Ewald", "None", "None", "None", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecEw_VdwNone_GeomW3W3_VF_sse2_double, "nb_kernel_ElecEw_VdwNone_GeomW3W3_VF_sse2_double", "sse2_double", "Ewald", "None", "None", "None", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecEw_VdwNone_GeomW3W3_F_sse2_double, "nb_kernel_ElecEw_VdwNone_GeomW3W3_F_sse2_double", "sse2_double", "Ewald", "None", "None", "None", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecEw_VdwNone_GeomW4P1_VF_sse2_double, "nb_kernel_ElecEw_VdwNone_GeomW4P1_VF_sse2_double", "sse2_double", "Ewald", "None", "None", "None", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEw_VdwNone_GeomW4P1_F_sse2_double, "nb_kernel_ElecEw_VdwNone_GeomW4P1_F_sse2_double", "sse2_double", "Ewald", "None", "None", "None", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecEw_VdwNone_GeomW4W4_VF_sse2_double, "nb_kernel_ElecEw_VdwNone_GeomW4W4_VF_sse2_double", "sse2_double", "Ewald", "None", "None", "None", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecEw_VdwNone_GeomW4W4_F_sse2_double, "nb_kernel_ElecEw_VdwNone_GeomW4W4_F_sse2_double", "sse2_double", "Ewald", "None", "None", "None", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecEw_VdwCSTab_GeomP1P1_VF_sse2_double, "nb_kernel_ElecEw_VdwCSTab_GeomP1P1_VF_sse2_double", "sse2_double", "Ewald", "None", "CubicSplineTable", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEw_VdwCSTab_GeomP1P1_F_sse2_double, "nb_kernel_ElecEw_VdwCSTab_GeomP1P1_F_sse2_double", "sse2_double", "Ewald", "None", "CubicSplineTable", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecEw_VdwCSTab_GeomW3P1_VF_sse2_double, "nb_kernel_ElecEw_VdwCSTab_GeomW3P1_VF_sse2_double", "sse2_double", "Ewald", "None", "CubicSplineTable", "None", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEw_VdwCSTab_GeomW3P1_F_sse2_double, "nb_kernel_ElecEw_VdwCSTab_GeomW3P1_F_sse2_double", "sse2_double", "Ewald", "None", "CubicSplineTable", "None", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecEw_VdwCSTab_GeomW3W3_VF_sse2_double, "nb_kernel_ElecEw_VdwCSTab_GeomW3W3_VF_sse2_double", "sse2_double", "Ewald", "None", "CubicSplineTable", "None", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecEw_VdwCSTab_GeomW3W3_F_sse2_double, "nb_kernel_ElecEw_VdwCSTab_GeomW3W3_F_sse2_double", "sse2_double", "Ewald", "None", "CubicSplineTable", "None", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecEw_VdwCSTab_GeomW4P1_VF_sse2_double, "nb_kernel_ElecEw_VdwCSTab_GeomW4P1_VF_sse2_double", "sse2_double", "Ewald", "None", "CubicSplineTable", "None", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEw_VdwCSTab_GeomW4P1_F_sse2_double, "nb_kernel_ElecEw_VdwCSTab_GeomW4P1_F_sse2_double", "sse2_double", "Ewald", "None", "CubicSplineTable", "None", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecEw_VdwCSTab_GeomW4W4_VF_sse2_double, "nb_kernel_ElecEw_VdwCSTab_GeomW4W4_VF_sse2_double", "sse2_double", "Ewald", "None", "CubicSplineTable", "None", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecEw_VdwCSTab_GeomW4W4_F_sse2_double, "nb_kernel_ElecEw_VdwCSTab_GeomW4W4_F_sse2_double", "sse2_double", "Ewald", "None", "CubicSplineTable", "None", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecEwSh_VdwLJSh_GeomP1P1_VF_sse2_double, "nb_kernel_ElecEwSh_VdwLJSh_GeomP1P1_VF_sse2_double", "sse2_double", "Ewald", "PotentialShift", "LennardJones", "PotentialShift", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSh_VdwLJSh_GeomP1P1_F_sse2_double, "nb_kernel_ElecEwSh_VdwLJSh_GeomP1P1_F_sse2_double", "sse2_double", "Ewald", "PotentialShift", "LennardJones", "PotentialShift", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecEwSh_VdwLJSh_GeomW3P1_VF_sse2_double, "nb_kernel_ElecEwSh_VdwLJSh_GeomW3P1_VF_sse2_double", "sse2_double", "Ewald", "PotentialShift", "LennardJones", "PotentialShift", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSh_VdwLJSh_GeomW3P1_F_sse2_double, "nb_kernel_ElecEwSh_VdwLJSh_GeomW3P1_F_sse2_double", "sse2_double", "Ewald", "PotentialShift", "LennardJones", "PotentialShift", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecEwSh_VdwLJSh_GeomW3W3_VF_sse2_double, "nb_kernel_ElecEwSh_VdwLJSh_GeomW3W3_VF_sse2_double", "sse2_double", "Ewald", "PotentialShift", "LennardJones", "PotentialShift", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSh_VdwLJSh_GeomW3W3_F_sse2_double, "nb_kernel_ElecEwSh_VdwLJSh_GeomW3W3_F_sse2_double", "sse2_double", "Ewald", "PotentialShift", "LennardJones", "PotentialShift", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecEwSh_VdwLJSh_GeomW4P1_VF_sse2_double, "nb_kernel_ElecEwSh_VdwLJSh_GeomW4P1_VF_sse2_double", "sse2_double", "Ewald", "PotentialShift", "LennardJones", "PotentialShift", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSh_VdwLJSh_GeomW4P1_F_sse2_double, "nb_kernel_ElecEwSh_VdwLJSh_GeomW4P1_F_sse2_double", "sse2_double", "Ewald", "PotentialShift", "LennardJones", "PotentialShift", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecEwSh_VdwLJSh_GeomW4W4_VF_sse2_double, "nb_kernel_ElecEwSh_VdwLJSh_GeomW4W4_VF_sse2_double", "sse2_double", "Ewald", "PotentialShift", "LennardJones", "PotentialShift", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSh_VdwLJSh_GeomW4W4_F_sse2_double, "nb_kernel_ElecEwSh_VdwLJSh_GeomW4W4_F_sse2_double", "sse2_double", "Ewald", "PotentialShift", "LennardJones", "PotentialShift", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecEwSh_VdwNone_GeomP1P1_VF_sse2_double, "nb_kernel_ElecEwSh_VdwNone_GeomP1P1_VF_sse2_double", "sse2_double", "Ewald", "PotentialShift", "None", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSh_VdwNone_GeomP1P1_F_sse2_double, "nb_kernel_ElecEwSh_VdwNone_GeomP1P1_F_sse2_double", "sse2_double", "Ewald", "PotentialShift", "None", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecEwSh_VdwNone_GeomW3P1_VF_sse2_double, "nb_kernel_ElecEwSh_VdwNone_GeomW3P1_VF_sse2_double", "sse2_double", "Ewald", "PotentialShift", "None", "None", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSh_VdwNone_GeomW3P1_F_sse2_double, "nb_kernel_ElecEwSh_VdwNone_GeomW3P1_F_sse2_double", "sse2_double", "Ewald", "PotentialShift", "None", "None", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecEwSh_VdwNone_GeomW3W3_VF_sse2_double, "nb_kernel_ElecEwSh_VdwNone_GeomW3W3_VF_sse2_double", "sse2_double", "Ewald", "PotentialShift", "None", "None", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSh_VdwNone_GeomW3W3_F_sse2_double, "nb_kernel_ElecEwSh_VdwNone_GeomW3W3_F_sse2_double", "sse2_double", "Ewald", "PotentialShift", "None", "None", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecEwSh_VdwNone_GeomW4P1_VF_sse2_double, "nb_kernel_ElecEwSh_VdwNone_GeomW4P1_VF_sse2_double", "sse2_double", "Ewald", "PotentialShift", "None", "None", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSh_VdwNone_GeomW4P1_F_sse2_double, "nb_kernel_ElecEwSh_VdwNone_GeomW4P1_F_sse2_double", "sse2_double", "Ewald", "PotentialShift", "None", "None", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecEwSh_VdwNone_GeomW4W4_VF_sse2_double, "nb_kernel_ElecEwSh_VdwNone_GeomW4W4_VF_sse2_double", "sse2_double", "Ewald", "PotentialShift", "None", "None", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSh_VdwNone_GeomW4W4_F_sse2_double, "nb_kernel_ElecEwSh_VdwNone_GeomW4W4_F_sse2_double", "sse2_double", "Ewald", "PotentialShift", "None", "None", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecEwSw_VdwLJSw_GeomP1P1_VF_sse2_double, "nb_kernel_ElecEwSw_VdwLJSw_GeomP1P1_VF_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "LennardJones", "PotentialSwitch", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSw_VdwLJSw_GeomP1P1_F_sse2_double, "nb_kernel_ElecEwSw_VdwLJSw_GeomP1P1_F_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "LennardJones", "PotentialSwitch", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecEwSw_VdwLJSw_GeomW3P1_VF_sse2_double, "nb_kernel_ElecEwSw_VdwLJSw_GeomW3P1_VF_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "LennardJones", "PotentialSwitch", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSw_VdwLJSw_GeomW3P1_F_sse2_double, "nb_kernel_ElecEwSw_VdwLJSw_GeomW3P1_F_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "LennardJones", "PotentialSwitch", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecEwSw_VdwLJSw_GeomW3W3_VF_sse2_double, "nb_kernel_ElecEwSw_VdwLJSw_GeomW3W3_VF_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "LennardJones", "PotentialSwitch", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSw_VdwLJSw_GeomW3W3_F_sse2_double, "nb_kernel_ElecEwSw_VdwLJSw_GeomW3W3_F_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "LennardJones", "PotentialSwitch", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecEwSw_VdwLJSw_GeomW4P1_VF_sse2_double, "nb_kernel_ElecEwSw_VdwLJSw_GeomW4P1_VF_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "LennardJones", "PotentialSwitch", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSw_VdwLJSw_GeomW4P1_F_sse2_double, "nb_kernel_ElecEwSw_VdwLJSw_GeomW4P1_F_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "LennardJones", "PotentialSwitch", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecEwSw_VdwLJSw_GeomW4W4_VF_sse2_double, "nb_kernel_ElecEwSw_VdwLJSw_GeomW4W4_VF_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "LennardJones", "PotentialSwitch", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSw_VdwLJSw_GeomW4W4_F_sse2_double, "nb_kernel_ElecEwSw_VdwLJSw_GeomW4W4_F_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "LennardJones", "PotentialSwitch", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecEwSw_VdwNone_GeomP1P1_VF_sse2_double, "nb_kernel_ElecEwSw_VdwNone_GeomP1P1_VF_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "None", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSw_VdwNone_GeomP1P1_F_sse2_double, "nb_kernel_ElecEwSw_VdwNone_GeomP1P1_F_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "None", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecEwSw_VdwNone_GeomW3P1_VF_sse2_double, "nb_kernel_ElecEwSw_VdwNone_GeomW3P1_VF_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "None", "None", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSw_VdwNone_GeomW3P1_F_sse2_double, "nb_kernel_ElecEwSw_VdwNone_GeomW3P1_F_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "None", "None", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecEwSw_VdwNone_GeomW3W3_VF_sse2_double, "nb_kernel_ElecEwSw_VdwNone_GeomW3W3_VF_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "None", "None", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSw_VdwNone_GeomW3W3_F_sse2_double, "nb_kernel_ElecEwSw_VdwNone_GeomW3W3_F_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "None", "None", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecEwSw_VdwNone_GeomW4P1_VF_sse2_double, "nb_kernel_ElecEwSw_VdwNone_GeomW4P1_VF_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "None", "None", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSw_VdwNone_GeomW4P1_F_sse2_double, "nb_kernel_ElecEwSw_VdwNone_GeomW4P1_F_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "None", "None", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecEwSw_VdwNone_GeomW4W4_VF_sse2_double, "nb_kernel_ElecEwSw_VdwNone_GeomW4W4_VF_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "None", "None", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecEwSw_VdwNone_GeomW4W4_F_sse2_double, "nb_kernel_ElecEwSw_VdwNone_GeomW4W4_F_sse2_double", "sse2_double", "Ewald", "PotentialSwitch", "None", "None", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecCoul_VdwLJ_GeomP1P1_VF_sse2_double, "nb_kernel_ElecCoul_VdwLJ_GeomP1P1_VF_sse2_double", "sse2_double", "Coulomb", "None", "LennardJones", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCoul_VdwLJ_GeomP1P1_F_sse2_double, "nb_kernel_ElecCoul_VdwLJ_GeomP1P1_F_sse2_double", "sse2_double", "Coulomb", "None", "LennardJones", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecCoul_VdwLJ_GeomW3P1_VF_sse2_double, "nb_kernel_ElecCoul_VdwLJ_GeomW3P1_VF_sse2_double", "sse2_double", "Coulomb", "None", "LennardJones", "None", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCoul_VdwLJ_GeomW3P1_F_sse2_double, "nb_kernel_ElecCoul_VdwLJ_GeomW3P1_F_sse2_double", "sse2_double", "Coulomb", "None", "LennardJones", "None", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecCoul_VdwLJ_GeomW3W3_VF_sse2_double, "nb_kernel_ElecCoul_VdwLJ_GeomW3W3_VF_sse2_double", "sse2_double", "Coulomb", "None", "LennardJones", "None", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecCoul_VdwLJ_GeomW3W3_F_sse2_double, "nb_kernel_ElecCoul_VdwLJ_GeomW3W3_F_sse2_double", "sse2_double", "Coulomb", "None", "LennardJones", "None", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecCoul_VdwLJ_GeomW4P1_VF_sse2_double, "nb_kernel_ElecCoul_VdwLJ_GeomW4P1_VF_sse2_double", "sse2_double", "Coulomb", "None", "LennardJones", "None", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCoul_VdwLJ_GeomW4P1_F_sse2_double, "nb_kernel_ElecCoul_VdwLJ_GeomW4P1_F_sse2_double", "sse2_double", "Coulomb", "None", "LennardJones", "None", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecCoul_VdwLJ_GeomW4W4_VF_sse2_double, "nb_kernel_ElecCoul_VdwLJ_GeomW4W4_VF_sse2_double", "sse2_double", "Coulomb", "None", "LennardJones", "None", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecCoul_VdwLJ_GeomW4W4_F_sse2_double, "nb_kernel_ElecCoul_VdwLJ_GeomW4W4_F_sse2_double", "sse2_double", "Coulomb", "None", "LennardJones", "None", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecCoul_VdwNone_GeomP1P1_VF_sse2_double, "nb_kernel_ElecCoul_VdwNone_GeomP1P1_VF_sse2_double", "sse2_double", "Coulomb", "None", "None", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCoul_VdwNone_GeomP1P1_F_sse2_double, "nb_kernel_ElecCoul_VdwNone_GeomP1P1_F_sse2_double", "sse2_double", "Coulomb", "None", "None", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecCoul_VdwNone_GeomW3P1_VF_sse2_double, "nb_kernel_ElecCoul_VdwNone_GeomW3P1_VF_sse2_double", "sse2_double", "Coulomb", "None", "None", "None", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCoul_VdwNone_GeomW3P1_F_sse2_double, "nb_kernel_ElecCoul_VdwNone_GeomW3P1_F_sse2_double", "sse2_double", "Coulomb", "None", "None", "None", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecCoul_VdwNone_GeomW3W3_VF_sse2_double, "nb_kernel_ElecCoul_VdwNone_GeomW3W3_VF_sse2_double", "sse2_double", "Coulomb", "None", "None", "None", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecCoul_VdwNone_GeomW3W3_F_sse2_double, "nb_kernel_ElecCoul_VdwNone_GeomW3W3_F_sse2_double", "sse2_double", "Coulomb", "None", "None", "None", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecCoul_VdwNone_GeomW4P1_VF_sse2_double, "nb_kernel_ElecCoul_VdwNone_GeomW4P1_VF_sse2_double", "sse2_double", "Coulomb", "None", "None", "None", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCoul_VdwNone_GeomW4P1_F_sse2_double, "nb_kernel_ElecCoul_VdwNone_GeomW4P1_F_sse2_double", "sse2_double", "Coulomb", "None", "None", "None", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecCoul_VdwNone_GeomW4W4_VF_sse2_double, "nb_kernel_ElecCoul_VdwNone_GeomW4W4_VF_sse2_double", "sse2_double", "Coulomb", "None", "None", "None", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecCoul_VdwNone_GeomW4W4_F_sse2_double, "nb_kernel_ElecCoul_VdwNone_GeomW4W4_F_sse2_double", "sse2_double", "Coulomb", "None", "None", "None", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecCoul_VdwCSTab_GeomP1P1_VF_sse2_double, "nb_kernel_ElecCoul_VdwCSTab_GeomP1P1_VF_sse2_double", "sse2_double", "Coulomb", "None", "CubicSplineTable", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCoul_VdwCSTab_GeomP1P1_F_sse2_double, "nb_kernel_ElecCoul_VdwCSTab_GeomP1P1_F_sse2_double", "sse2_double", "Coulomb", "None", "CubicSplineTable", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecCoul_VdwCSTab_GeomW3P1_VF_sse2_double, "nb_kernel_ElecCoul_VdwCSTab_GeomW3P1_VF_sse2_double", "sse2_double", "Coulomb", "None", "CubicSplineTable", "None", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCoul_VdwCSTab_GeomW3P1_F_sse2_double, "nb_kernel_ElecCoul_VdwCSTab_GeomW3P1_F_sse2_double", "sse2_double", "Coulomb", "None", "CubicSplineTable", "None", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecCoul_VdwCSTab_GeomW3W3_VF_sse2_double, "nb_kernel_ElecCoul_VdwCSTab_GeomW3W3_VF_sse2_double", "sse2_double", "Coulomb", "None", "CubicSplineTable", "None", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecCoul_VdwCSTab_GeomW3W3_F_sse2_double, "nb_kernel_ElecCoul_VdwCSTab_GeomW3W3_F_sse2_double", "sse2_double", "Coulomb", "None", "CubicSplineTable", "None", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecCoul_VdwCSTab_GeomW4P1_VF_sse2_double, "nb_kernel_ElecCoul_VdwCSTab_GeomW4P1_VF_sse2_double", "sse2_double", "Coulomb", "None", "CubicSplineTable", "None", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCoul_VdwCSTab_GeomW4P1_F_sse2_double, "nb_kernel_ElecCoul_VdwCSTab_GeomW4P1_F_sse2_double", "sse2_double", "Coulomb", "None", "CubicSplineTable", "None", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecCoul_VdwCSTab_GeomW4W4_VF_sse2_double, "nb_kernel_ElecCoul_VdwCSTab_GeomW4W4_VF_sse2_double", "sse2_double", "Coulomb", "None", "CubicSplineTable", "None", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecCoul_VdwCSTab_GeomW4W4_F_sse2_double, "nb_kernel_ElecCoul_VdwCSTab_GeomW4W4_F_sse2_double", "sse2_double", "Coulomb", "None", "CubicSplineTable", "None", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecCSTab_VdwLJ_GeomP1P1_VF_sse2_double, "nb_kernel_ElecCSTab_VdwLJ_GeomP1P1_VF_sse2_double", "sse2_double", "CubicSplineTable", "None", "LennardJones", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCSTab_VdwLJ_GeomP1P1_F_sse2_double, "nb_kernel_ElecCSTab_VdwLJ_GeomP1P1_F_sse2_double", "sse2_double", "CubicSplineTable", "None", "LennardJones", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecCSTab_VdwLJ_GeomW3P1_VF_sse2_double, "nb_kernel_ElecCSTab_VdwLJ_GeomW3P1_VF_sse2_double", "sse2_double", "CubicSplineTable", "None", "LennardJones", "None", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCSTab_VdwLJ_GeomW3P1_F_sse2_double, "nb_kernel_ElecCSTab_VdwLJ_GeomW3P1_F_sse2_double", "sse2_double", "CubicSplineTable", "None", "LennardJones", "None", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecCSTab_VdwLJ_GeomW3W3_VF_sse2_double, "nb_kernel_ElecCSTab_VdwLJ_GeomW3W3_VF_sse2_double", "sse2_double", "CubicSplineTable", "None", "LennardJones", "None", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecCSTab_VdwLJ_GeomW3W3_F_sse2_double, "nb_kernel_ElecCSTab_VdwLJ_GeomW3W3_F_sse2_double", "sse2_double", "CubicSplineTable", "None", "LennardJones", "None", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecCSTab_VdwLJ_GeomW4P1_VF_sse2_double, "nb_kernel_ElecCSTab_VdwLJ_GeomW4P1_VF_sse2_double", "sse2_double", "CubicSplineTable", "None", "LennardJones", "None", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCSTab_VdwLJ_GeomW4P1_F_sse2_double, "nb_kernel_ElecCSTab_VdwLJ_GeomW4P1_F_sse2_double", "sse2_double", "CubicSplineTable", "None", "LennardJones", "None", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecCSTab_VdwLJ_GeomW4W4_VF_sse2_double, "nb_kernel_ElecCSTab_VdwLJ_GeomW4W4_VF_sse2_double", "sse2_double", "CubicSplineTable", "None", "LennardJones", "None", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecCSTab_VdwLJ_GeomW4W4_F_sse2_double, "nb_kernel_ElecCSTab_VdwLJ_GeomW4W4_F_sse2_double", "sse2_double", "CubicSplineTable", "None", "LennardJones", "None", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecCSTab_VdwNone_GeomP1P1_VF_sse2_double, "nb_kernel_ElecCSTab_VdwNone_GeomP1P1_VF_sse2_double", "sse2_double", "CubicSplineTable", "None", "None", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCSTab_VdwNone_GeomP1P1_F_sse2_double, "nb_kernel_ElecCSTab_VdwNone_GeomP1P1_F_sse2_double", "sse2_double", "CubicSplineTable", "None", "None", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecCSTab_VdwNone_GeomW3P1_VF_sse2_double, "nb_kernel_ElecCSTab_VdwNone_GeomW3P1_VF_sse2_double", "sse2_double", "CubicSplineTable", "None", "None", "None", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCSTab_VdwNone_GeomW3P1_F_sse2_double, "nb_kernel_ElecCSTab_VdwNone_GeomW3P1_F_sse2_double", "sse2_double", "CubicSplineTable", "None", "None", "None", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecCSTab_VdwNone_GeomW3W3_VF_sse2_double, "nb_kernel_ElecCSTab_VdwNone_GeomW3W3_VF_sse2_double", "sse2_double", "CubicSplineTable", "None", "None", "None", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecCSTab_VdwNone_GeomW3W3_F_sse2_double, "nb_kernel_ElecCSTab_VdwNone_GeomW3W3_F_sse2_double", "sse2_double", "CubicSplineTable", "None", "None", "None", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecCSTab_VdwNone_GeomW4P1_VF_sse2_double, "nb_kernel_ElecCSTab_VdwNone_GeomW4P1_VF_sse2_double", "sse2_double", "CubicSplineTable", "None", "None", "None", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCSTab_VdwNone_GeomW4P1_F_sse2_double, "nb_kernel_ElecCSTab_VdwNone_GeomW4P1_F_sse2_double", "sse2_double", "CubicSplineTable", "None", "None", "None", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecCSTab_VdwNone_GeomW4W4_VF_sse2_double, "nb_kernel_ElecCSTab_VdwNone_GeomW4W4_VF_sse2_double", "sse2_double", "CubicSplineTable", "None", "None", "None", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecCSTab_VdwNone_GeomW4W4_F_sse2_double, "nb_kernel_ElecCSTab_VdwNone_GeomW4W4_F_sse2_double", "sse2_double", "CubicSplineTable", "None", "None", "None", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecCSTab_VdwCSTab_GeomP1P1_VF_sse2_double, "nb_kernel_ElecCSTab_VdwCSTab_GeomP1P1_VF_sse2_double", "sse2_double", "CubicSplineTable", "None", "CubicSplineTable", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCSTab_VdwCSTab_GeomP1P1_F_sse2_double, "nb_kernel_ElecCSTab_VdwCSTab_GeomP1P1_F_sse2_double", "sse2_double", "CubicSplineTable", "None", "CubicSplineTable", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecCSTab_VdwCSTab_GeomW3P1_VF_sse2_double, "nb_kernel_ElecCSTab_VdwCSTab_GeomW3P1_VF_sse2_double", "sse2_double", "CubicSplineTable", "None", "CubicSplineTable", "None", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCSTab_VdwCSTab_GeomW3P1_F_sse2_double, "nb_kernel_ElecCSTab_VdwCSTab_GeomW3P1_F_sse2_double", "sse2_double", "CubicSplineTable", "None", "CubicSplineTable", "None", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecCSTab_VdwCSTab_GeomW3W3_VF_sse2_double, "nb_kernel_ElecCSTab_VdwCSTab_GeomW3W3_VF_sse2_double", "sse2_double", "CubicSplineTable", "None", "CubicSplineTable", "None", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecCSTab_VdwCSTab_GeomW3W3_F_sse2_double, "nb_kernel_ElecCSTab_VdwCSTab_GeomW3W3_F_sse2_double", "sse2_double", "CubicSplineTable", "None", "CubicSplineTable", "None", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecCSTab_VdwCSTab_GeomW4P1_VF_sse2_double, "nb_kernel_ElecCSTab_VdwCSTab_GeomW4P1_VF_sse2_double", "sse2_double", "CubicSplineTable", "None", "CubicSplineTable", "None", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecCSTab_VdwCSTab_GeomW4P1_F_sse2_double, "nb_kernel_ElecCSTab_VdwCSTab_GeomW4P1_F_sse2_double", "sse2_double", "CubicSplineTable", "None", "CubicSplineTable", "None", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecCSTab_VdwCSTab_GeomW4W4_VF_sse2_double, "nb_kernel_ElecCSTab_VdwCSTab_GeomW4W4_VF_sse2_double", "sse2_double", "CubicSplineTable", "None", "CubicSplineTable", "None", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecCSTab_VdwCSTab_GeomW4W4_F_sse2_double, "nb_kernel_ElecCSTab_VdwCSTab_GeomW4W4_F_sse2_double", "sse2_double", "CubicSplineTable", "None", "CubicSplineTable", "None", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecGB_VdwLJ_GeomP1P1_VF_sse2_double, "nb_kernel_ElecGB_VdwLJ_GeomP1P1_VF_sse2_double", "sse2_double", "GeneralizedBorn", "None", "LennardJones", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecGB_VdwLJ_GeomP1P1_F_sse2_double, "nb_kernel_ElecGB_VdwLJ_GeomP1P1_F_sse2_double", "sse2_double", "GeneralizedBorn", "None", "LennardJones", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecGB_VdwNone_GeomP1P1_VF_sse2_double, "nb_kernel_ElecGB_VdwNone_GeomP1P1_VF_sse2_double", "sse2_double", "GeneralizedBorn", "None", "None", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecGB_VdwNone_GeomP1P1_F_sse2_double, "nb_kernel_ElecGB_VdwNone_GeomP1P1_F_sse2_double", "sse2_double", "GeneralizedBorn", "None", "None", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecGB_VdwCSTab_GeomP1P1_VF_sse2_double, "nb_kernel_ElecGB_VdwCSTab_GeomP1P1_VF_sse2_double", "sse2_double", "GeneralizedBorn", "None", "CubicSplineTable", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecGB_VdwCSTab_GeomP1P1_F_sse2_double, "nb_kernel_ElecGB_VdwCSTab_GeomP1P1_F_sse2_double", "sse2_double", "GeneralizedBorn", "None", "CubicSplineTable", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwLJSh_GeomP1P1_VF_sse2_double, "nb_kernel_ElecRFCut_VdwLJSh_GeomP1P1_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialShift", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwLJSh_GeomP1P1_F_sse2_double, "nb_kernel_ElecRFCut_VdwLJSh_GeomP1P1_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialShift", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwLJSh_GeomW3P1_VF_sse2_double, "nb_kernel_ElecRFCut_VdwLJSh_GeomW3P1_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialShift", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwLJSh_GeomW3P1_F_sse2_double, "nb_kernel_ElecRFCut_VdwLJSh_GeomW3P1_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialShift", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwLJSh_GeomW3W3_VF_sse2_double, "nb_kernel_ElecRFCut_VdwLJSh_GeomW3W3_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialShift", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwLJSh_GeomW3W3_F_sse2_double, "nb_kernel_ElecRFCut_VdwLJSh_GeomW3W3_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialShift", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwLJSh_GeomW4P1_VF_sse2_double, "nb_kernel_ElecRFCut_VdwLJSh_GeomW4P1_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialShift", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwLJSh_GeomW4P1_F_sse2_double, "nb_kernel_ElecRFCut_VdwLJSh_GeomW4P1_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialShift", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwLJSh_GeomW4W4_VF_sse2_double, "nb_kernel_ElecRFCut_VdwLJSh_GeomW4W4_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialShift", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwLJSh_GeomW4W4_F_sse2_double, "nb_kernel_ElecRFCut_VdwLJSh_GeomW4W4_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialShift", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwLJSw_GeomP1P1_VF_sse2_double, "nb_kernel_ElecRFCut_VdwLJSw_GeomP1P1_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialSwitch", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwLJSw_GeomP1P1_F_sse2_double, "nb_kernel_ElecRFCut_VdwLJSw_GeomP1P1_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialSwitch", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwLJSw_GeomW3P1_VF_sse2_double, "nb_kernel_ElecRFCut_VdwLJSw_GeomW3P1_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialSwitch", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwLJSw_GeomW3P1_F_sse2_double, "nb_kernel_ElecRFCut_VdwLJSw_GeomW3P1_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialSwitch", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwLJSw_GeomW3W3_VF_sse2_double, "nb_kernel_ElecRFCut_VdwLJSw_GeomW3W3_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialSwitch", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwLJSw_GeomW3W3_F_sse2_double, "nb_kernel_ElecRFCut_VdwLJSw_GeomW3W3_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialSwitch", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwLJSw_GeomW4P1_VF_sse2_double, "nb_kernel_ElecRFCut_VdwLJSw_GeomW4P1_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialSwitch", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwLJSw_GeomW4P1_F_sse2_double, "nb_kernel_ElecRFCut_VdwLJSw_GeomW4P1_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialSwitch", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwLJSw_GeomW4W4_VF_sse2_double, "nb_kernel_ElecRFCut_VdwLJSw_GeomW4W4_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialSwitch", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwLJSw_GeomW4W4_F_sse2_double, "nb_kernel_ElecRFCut_VdwLJSw_GeomW4W4_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "LennardJones", "PotentialSwitch", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwNone_GeomP1P1_VF_sse2_double, "nb_kernel_ElecRFCut_VdwNone_GeomP1P1_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "None", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwNone_GeomP1P1_F_sse2_double, "nb_kernel_ElecRFCut_VdwNone_GeomP1P1_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "None", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwNone_GeomW3P1_VF_sse2_double, "nb_kernel_ElecRFCut_VdwNone_GeomW3P1_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "None", "None", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwNone_GeomW3P1_F_sse2_double, "nb_kernel_ElecRFCut_VdwNone_GeomW3P1_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "None", "None", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwNone_GeomW3W3_VF_sse2_double, "nb_kernel_ElecRFCut_VdwNone_GeomW3W3_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "None", "None", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwNone_GeomW3W3_F_sse2_double, "nb_kernel_ElecRFCut_VdwNone_GeomW3W3_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "None", "None", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwNone_GeomW4P1_VF_sse2_double, "nb_kernel_ElecRFCut_VdwNone_GeomW4P1_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "None", "None", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwNone_GeomW4P1_F_sse2_double, "nb_kernel_ElecRFCut_VdwNone_GeomW4P1_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "None", "None", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwNone_GeomW4W4_VF_sse2_double, "nb_kernel_ElecRFCut_VdwNone_GeomW4W4_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "None", "None", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwNone_GeomW4W4_F_sse2_double, "nb_kernel_ElecRFCut_VdwNone_GeomW4W4_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "None", "None", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwCSTab_GeomP1P1_VF_sse2_double, "nb_kernel_ElecRFCut_VdwCSTab_GeomP1P1_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "CubicSplineTable", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwCSTab_GeomP1P1_F_sse2_double, "nb_kernel_ElecRFCut_VdwCSTab_GeomP1P1_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "CubicSplineTable", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwCSTab_GeomW3P1_VF_sse2_double, "nb_kernel_ElecRFCut_VdwCSTab_GeomW3P1_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "CubicSplineTable", "None", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwCSTab_GeomW3P1_F_sse2_double, "nb_kernel_ElecRFCut_VdwCSTab_GeomW3P1_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "CubicSplineTable", "None", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwCSTab_GeomW3W3_VF_sse2_double, "nb_kernel_ElecRFCut_VdwCSTab_GeomW3W3_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "CubicSplineTable", "None", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwCSTab_GeomW3W3_F_sse2_double, "nb_kernel_ElecRFCut_VdwCSTab_GeomW3W3_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "CubicSplineTable", "None", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwCSTab_GeomW4P1_VF_sse2_double, "nb_kernel_ElecRFCut_VdwCSTab_GeomW4P1_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "CubicSplineTable", "None", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwCSTab_GeomW4P1_F_sse2_double, "nb_kernel_ElecRFCut_VdwCSTab_GeomW4P1_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "CubicSplineTable", "None", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecRFCut_VdwCSTab_GeomW4W4_VF_sse2_double, "nb_kernel_ElecRFCut_VdwCSTab_GeomW4W4_VF_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "CubicSplineTable", "None", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecRFCut_VdwCSTab_GeomW4W4_F_sse2_double, "nb_kernel_ElecRFCut_VdwCSTab_GeomW4W4_F_sse2_double", "sse2_double", "ReactionField", "ExactCutoff", "CubicSplineTable", "None", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecRF_VdwLJ_GeomP1P1_VF_sse2_double, "nb_kernel_ElecRF_VdwLJ_GeomP1P1_VF_sse2_double", "sse2_double", "ReactionField", "None", "LennardJones", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRF_VdwLJ_GeomP1P1_F_sse2_double, "nb_kernel_ElecRF_VdwLJ_GeomP1P1_F_sse2_double", "sse2_double", "ReactionField", "None", "LennardJones", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecRF_VdwLJ_GeomW3P1_VF_sse2_double, "nb_kernel_ElecRF_VdwLJ_GeomW3P1_VF_sse2_double", "sse2_double", "ReactionField", "None", "LennardJones", "None", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRF_VdwLJ_GeomW3P1_F_sse2_double, "nb_kernel_ElecRF_VdwLJ_GeomW3P1_F_sse2_double", "sse2_double", "ReactionField", "None", "LennardJones", "None", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecRF_VdwLJ_GeomW3W3_VF_sse2_double, "nb_kernel_ElecRF_VdwLJ_GeomW3W3_VF_sse2_double", "sse2_double", "ReactionField", "None", "LennardJones", "None", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecRF_VdwLJ_GeomW3W3_F_sse2_double, "nb_kernel_ElecRF_VdwLJ_GeomW3W3_F_sse2_double", "sse2_double", "ReactionField", "None", "LennardJones", "None", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecRF_VdwLJ_GeomW4P1_VF_sse2_double, "nb_kernel_ElecRF_VdwLJ_GeomW4P1_VF_sse2_double", "sse2_double", "ReactionField", "None", "LennardJones", "None", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRF_VdwLJ_GeomW4P1_F_sse2_double, "nb_kernel_ElecRF_VdwLJ_GeomW4P1_F_sse2_double", "sse2_double", "ReactionField", "None", "LennardJones", "None", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecRF_VdwLJ_GeomW4W4_VF_sse2_double, "nb_kernel_ElecRF_VdwLJ_GeomW4W4_VF_sse2_double", "sse2_double", "ReactionField", "None", "LennardJones", "None", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecRF_VdwLJ_GeomW4W4_F_sse2_double, "nb_kernel_ElecRF_VdwLJ_GeomW4W4_F_sse2_double", "sse2_double", "ReactionField", "None", "LennardJones", "None", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecRF_VdwNone_GeomP1P1_VF_sse2_double, "nb_kernel_ElecRF_VdwNone_GeomP1P1_VF_sse2_double", "sse2_double", "ReactionField", "None", "None", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRF_VdwNone_GeomP1P1_F_sse2_double, "nb_kernel_ElecRF_VdwNone_GeomP1P1_F_sse2_double", "sse2_double", "ReactionField", "None", "None", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecRF_VdwNone_GeomW3P1_VF_sse2_double, "nb_kernel_ElecRF_VdwNone_GeomW3P1_VF_sse2_double", "sse2_double", "ReactionField", "None", "None", "None", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRF_VdwNone_GeomW3P1_F_sse2_double, "nb_kernel_ElecRF_VdwNone_GeomW3P1_F_sse2_double", "sse2_double", "ReactionField", "None", "None", "None", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecRF_VdwNone_GeomW3W3_VF_sse2_double, "nb_kernel_ElecRF_VdwNone_GeomW3W3_VF_sse2_double", "sse2_double", "ReactionField", "None", "None", "None", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecRF_VdwNone_GeomW3W3_F_sse2_double, "nb_kernel_ElecRF_VdwNone_GeomW3W3_F_sse2_double", "sse2_double", "ReactionField", "None", "None", "None", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecRF_VdwNone_GeomW4P1_VF_sse2_double, "nb_kernel_ElecRF_VdwNone_GeomW4P1_VF_sse2_double", "sse2_double", "ReactionField", "None", "None", "None", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRF_VdwNone_GeomW4P1_F_sse2_double, "nb_kernel_ElecRF_VdwNone_GeomW4P1_F_sse2_double", "sse2_double", "ReactionField", "None", "None", "None", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecRF_VdwNone_GeomW4W4_VF_sse2_double, "nb_kernel_ElecRF_VdwNone_GeomW4W4_VF_sse2_double", "sse2_double", "ReactionField", "None", "None", "None", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecRF_VdwNone_GeomW4W4_F_sse2_double, "nb_kernel_ElecRF_VdwNone_GeomW4W4_F_sse2_double", "sse2_double", "ReactionField", "None", "None", "None", "Water4Water4", "", "Force" },
+ { nb_kernel_ElecRF_VdwCSTab_GeomP1P1_VF_sse2_double, "nb_kernel_ElecRF_VdwCSTab_GeomP1P1_VF_sse2_double", "sse2_double", "ReactionField", "None", "CubicSplineTable", "None", "ParticleParticle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRF_VdwCSTab_GeomP1P1_F_sse2_double, "nb_kernel_ElecRF_VdwCSTab_GeomP1P1_F_sse2_double", "sse2_double", "ReactionField", "None", "CubicSplineTable", "None", "ParticleParticle", "", "Force" },
+ { nb_kernel_ElecRF_VdwCSTab_GeomW3P1_VF_sse2_double, "nb_kernel_ElecRF_VdwCSTab_GeomW3P1_VF_sse2_double", "sse2_double", "ReactionField", "None", "CubicSplineTable", "None", "Water3Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRF_VdwCSTab_GeomW3P1_F_sse2_double, "nb_kernel_ElecRF_VdwCSTab_GeomW3P1_F_sse2_double", "sse2_double", "ReactionField", "None", "CubicSplineTable", "None", "Water3Particle", "", "Force" },
+ { nb_kernel_ElecRF_VdwCSTab_GeomW3W3_VF_sse2_double, "nb_kernel_ElecRF_VdwCSTab_GeomW3W3_VF_sse2_double", "sse2_double", "ReactionField", "None", "CubicSplineTable", "None", "Water3Water3", "", "PotentialAndForce" },
+ { nb_kernel_ElecRF_VdwCSTab_GeomW3W3_F_sse2_double, "nb_kernel_ElecRF_VdwCSTab_GeomW3W3_F_sse2_double", "sse2_double", "ReactionField", "None", "CubicSplineTable", "None", "Water3Water3", "", "Force" },
+ { nb_kernel_ElecRF_VdwCSTab_GeomW4P1_VF_sse2_double, "nb_kernel_ElecRF_VdwCSTab_GeomW4P1_VF_sse2_double", "sse2_double", "ReactionField", "None", "CubicSplineTable", "None", "Water4Particle", "", "PotentialAndForce" },
+ { nb_kernel_ElecRF_VdwCSTab_GeomW4P1_F_sse2_double, "nb_kernel_ElecRF_VdwCSTab_GeomW4P1_F_sse2_double", "sse2_double", "ReactionField", "None", "CubicSplineTable", "None", "Water4Particle", "", "Force" },
+ { nb_kernel_ElecRF_VdwCSTab_GeomW4W4_VF_sse2_double, "nb_kernel_ElecRF_VdwCSTab_GeomW4W4_VF_sse2_double", "sse2_double", "ReactionField", "None", "CubicSplineTable", "None", "Water4Water4", "", "PotentialAndForce" },
+ { nb_kernel_ElecRF_VdwCSTab_GeomW4W4_F_sse2_double, "nb_kernel_ElecRF_VdwCSTab_GeomW4W4_F_sse2_double", "sse2_double", "ReactionField", "None", "CubicSplineTable", "None", "Water4Water4", "", "Force" }
};
+int
+kernellist_sse2_double_size = sizeof(kernellist_sse2_double)/sizeof(kernellist_sse2_double[0]);
-/* Return 0 if SSE support is present, or
- * non-zero on failure.
- */
-int
-nb_kernel_sse2_double_test(FILE * log)
-{
- unsigned int level;
- unsigned int _eax,_ebx,_ecx,_edx;
- int status;
- int CPUInfo[4];
-
- if(NULL != log)
- {
- fprintf(log,"Checking CPU SSE2 support... ");
- }
-
- level = 1;
-#ifdef _MSC_VER
- __cpuid(CPUInfo,1);
-
- _eax=CPUInfo[0];
- _ebx=CPUInfo[1];
- _ecx=CPUInfo[2];
- _edx=CPUInfo[3];
-
-#elif defined(__x86_64__)
- /* GCC 64-bit inline asm */
- __asm__ ("push %%rbx\n\tcpuid\n\tpop %%rbx\n" \
- : "=a" (_eax), "=S" (_ebx), "=c" (_ecx), "=d" (_edx) \
- : "0" (level));
-#elif defined(__i386__)
- __asm__ ("push %%ebx\n\tcpuid\n\tpop %%ebx\n" \
- : "=a" (_eax), "=S" (_ebx), "=c" (_ecx), "=d" (_edx) \
- : "0" (level));
-#else
- if(NULL != log)
- {
- fprintf(log,"Don't know how to call cpuid() on this system!\n");
- }
- _eax=_ebx=_ecx=_edx=0;
#endif
-
- /* Features:
- *
- * SSE Bit 25 of edx should be set
- * SSE2 Bit 26 of edx should be set
- * SSE3 Bit 0 of ecx should be set
- * SSE4.1 Bit 19 of ecx should be set
- */
- status = (_edx & (1 << 26)) != 0;
-
- if(NULL != log)
- {
- fprintf(log,"%s present.", (status==0) ? "not" : "");
- }
-
- /* Return SSE2 status */
- return status;
-}
-
-
-
-
-void
-nb_kernel_setup_sse2_double(FILE *log,nb_kernel_t **list)
-{
- int i;
- nb_kernel_t *p;
-
- if(nb_kernel_sse2_double_test(log) == 0)
- {
- return;
- }
-
- for(i=0;i<eNR_NBKERNEL_NR;i++)
- {
- p = kernellist_sse2_double[i];
- if(p!=NULL)
- {
- list[i] = p;
- }
- }
-}
-
-
-
-
-
-/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
+/*
+ * Note: this file was generated by the Gromacs c kernel generator.
*
- * This file is part of Gromacs Copyright (c) 1991-2004
- * David van der Spoel, Erik Lindahl, University of Groningen.
+ * This source code is part of
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * G R O M A C S
*
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org
- *
- * And Hey:
- * Gnomes, ROck Monsters And Chili Sauce
- */
-#ifndef _NB_KERNEL_SSE2_DOUBLE_H_
-#define _NB_KERNEL_SSE2_DOUBLE_H_
-
-/*! \file nb_kernel_sse2_double.h
- * \brief SSE2-intrinsics optimized level2 nonbonded kernels.
+ * Copyright (c) 2001-2012, The GROMACS Development Team
+ *
+ * Gromacs is a library for molecular simulation and trajectory analysis,
+ * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
+ * a full list of developers and information, check out http://www.gromacs.org
*
- * \internal
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * To help fund GROMACS development, we humbly ask that you cite
+ * the papers people have written on it - you can find them on the website.
*/
-
-#include <stdio.h>
-
-#include <types/simple.h>
+#ifndef nb_kernel_sse2_double_h
+#define nb_kernel_sse2_double_h
#include "../nb_kernel.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-#if 0
-}
-#endif
+/* List of kernels for this architecture with metadata about them */
+extern nb_kernel_info_t
+kernellist_sse2_double[];
-void
-nb_kernel_setup_sse2_double(FILE *log,nb_kernel_t **list);
+/* Length of kernellist_c */
+extern int
+kernellist_sse2_double_size;
-#ifdef __cplusplus
-}
#endif
-
-#endif /* _NB_KERNEL_SSE2_DOUBLE_H_ */
--- /dev/null
+/* #if 0 */
+#error This file must be processed with the Gromacs pre-preprocessor
+/* #endif */
+/* #if INCLUDE_HEADER */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "../nb_kernel.h"
+#include "types/simple.h"
+#include "vec.h"
+#include "nrnb.h"
+
+#include "gmx_math_x86_sse2_double.h"
+#include "kernelutil_x86_sse2_double.h"
+/* #endif */
+
+/* ## List of variables set by the generating script: */
+/* ## */
+/* ## Setttings that apply to the entire kernel: */
+/* ## KERNEL_ELEC: String, choice for electrostatic interactions */
+/* ## KERNEL_VDW: String, choice for van der Waals interactions */
+/* ## KERNEL_NAME: String, name of this kernel */
+/* ## KERNEL_VF: String telling if we calculate potential, force, or both */
+/* ## GEOMETRY_I/GEOMETRY_J: String, name of each geometry, e.g. 'Water3' or '1Particle' */
+/* ## */
+/* ## Setttings that apply to particles in the outer (I) or inner (J) loops: */
+/* ## PARTICLES_I[]/ Arrays with lists of i/j particles to use in kernel. It is */
+/* ## PARTICLES_J[]: just [0] for particle geometry, but can be longer for water */
+/* ## PARTICLES_ELEC_I[]/ Arrays with lists of i/j particle that have electrostatics */
+/* ## PARTICLES_ELEC_J[]: interactions that should be calculated in this kernel. */
+/* ## PARTICLES_VDW_I[]/ Arrays with the list of i/j particle that have VdW */
+/* ## PARTICLES_VDW_J[]: interactions that should be calculated in this kernel. */
+/* ## */
+/* ## Setttings for pairs of interactions (e.g. 2nd i particle against 1st j particle) */
+/* ## PAIRS_IJ[]: Array with (i,j) tuples of pairs for which interactions */
+/* ## should be calculated in this kernel. Zero-charge particles */
+/* ## do not have interactions with particles without vdw, and */
+/* ## Vdw-only interactions are not evaluated in a no-vdw-kernel. */
+/* ## INTERACTION_FLAGS[][]: 2D matrix, dimension e.g. 3*3 for water-water interactions. */
+/* ## For each i-j pair, the element [I][J] is a list of strings */
+/* ## defining properties/flags of this interaction. Examples */
+/* ## include 'electrostatics'/'vdw' if that type of interaction */
+/* ## should be evaluated, 'rsq'/'rinv'/'rinvsq' if those values */
+/* ## are needed, and 'exactcutoff' or 'shift','switch' to */
+/* ## decide if the force/potential should be modified. This way */
+/* ## we only calculate values absolutely needed for each case. */
+
+/* ## Calculate the size and offset for (merged/interleaved) table data */
+
+/*
+ * Gromacs nonbonded kernel: {KERNEL_NAME}
+ * Electrostatics interaction: {KERNEL_ELEC}
+ * VdW interaction: {KERNEL_VDW}
+ * Geometry: {GEOMETRY_I}-{GEOMETRY_J}
+ * Calculate force/pot: {KERNEL_VF}
+ */
+void
+{KERNEL_NAME}
+ (t_nblist * gmx_restrict nlist,
+ rvec * gmx_restrict xx,
+ rvec * gmx_restrict ff,
+ t_forcerec * gmx_restrict fr,
+ t_mdatoms * gmx_restrict mdatoms,
+ nb_kernel_data_t * gmx_restrict kernel_data,
+ t_nrnb * gmx_restrict nrnb)
+{
+ /* ## Not all variables are used for all kernels, but any optimizing compiler fixes that, */
+ /* ## so there is no point in going to extremes to exclude variables that are not needed. */
+ /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
+ * just 0 for non-waters.
+ * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
+ * jnr indices corresponding to data put in the four positions in the SIMD register.
+ */
+ int i_shift_offset,i_coord_offset,outeriter,inneriter;
+ int j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
+ int jnrA,jnrB;
+ int j_coord_offsetA,j_coord_offsetB;
+ int *iinr,*jindex,*jjnr,*shiftidx,*gid;
+ real rcutoff_scalar;
+ real *shiftvec,*fshift,*x,*f;
+ __m128d tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
+ /* #for I in PARTICLES_I */
+ int vdwioffset{I};
+ __m128d ix{I},iy{I},iz{I},fix{I},fiy{I},fiz{I},iq{I},isai{I};
+ /* #endfor */
+ /* #for J in PARTICLES_J */
+ int vdwjidx{J}A,vdwjidx{J}B;
+ __m128d jx{J},jy{J},jz{J},fjx{J},fjy{J},fjz{J},jq{J},isaj{J};
+ /* #endfor */
+ /* #for I,J in PAIRS_IJ */
+ __m128d dx{I}{J},dy{I}{J},dz{I}{J},rsq{I}{J},rinv{I}{J},rinvsq{I}{J},r{I}{J},qq{I}{J},c6_{I}{J},c12_{I}{J};
+ /* #endfor */
+ /* #if KERNEL_ELEC != 'None' */
+ __m128d velec,felec,velecsum,facel,crf,krf,krf2;
+ real *charge;
+ /* #endif */
+ /* #if 'GeneralizedBorn' in KERNEL_ELEC */
+ __m128i gbitab;
+ __m128d vgb,fgb,vgbsum,dvdasum,gbscale,gbtabscale,isaprod,gbqqfactor,gbinvepsdiff,dvdaj,gbeps,dvdatmp;
+ __m128d minushalf = _mm_set1_pd(-0.5);
+ real *invsqrta,*dvda,*gbtab;
+ /* #endif */
+ /* #if KERNEL_VDW != 'None' */
+ int nvdwtype;
+ __m128d rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
+ int *vdwtype;
+ real *vdwparam;
+ __m128d one_sixth = _mm_set1_pd(1.0/6.0);
+ __m128d one_twelfth = _mm_set1_pd(1.0/12.0);
+ /* #endif */
+ /* #if 'Table' in KERNEL_ELEC or 'GeneralizedBorn' in KERNEL_ELEC or 'Table' in KERNEL_VDW */
+ __m128i vfitab;
+ __m128i ifour = _mm_set1_epi32(4);
+ __m128d rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
+ real *vftab;
+ /* #endif */
+ /* #if 'Ewald' in KERNEL_ELEC */
+ __m128i ewitab;
+ __m128d ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
+ real *ewtab;
+ /* #endif */
+ /* #if 'PotentialSwitch' in [KERNEL_MOD_ELEC,KERNEL_MOD_VDW] */
+ __m128d rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
+ real rswitch_scalar,d_scalar;
+ /* #endif */
+ __m128d dummy_mask,cutoff_mask;
+ __m128d signbit = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
+ __m128d one = _mm_set1_pd(1.0);
+ __m128d two = _mm_set1_pd(2.0);
+ x = xx[0];
+ f = ff[0];
+
+ nri = nlist->nri;
+ iinr = nlist->iinr;
+ jindex = nlist->jindex;
+ jjnr = nlist->jjnr;
+ shiftidx = nlist->shift;
+ gid = nlist->gid;
+ shiftvec = fr->shift_vec[0];
+ fshift = fr->fshift[0];
+ /* #if KERNEL_ELEC != 'None' */
+ facel = _mm_set1_pd(fr->epsfac);
+ charge = mdatoms->chargeA;
+ /* #if 'ReactionField' in KERNEL_ELEC */
+ krf = _mm_set1_pd(fr->ic->k_rf);
+ krf2 = _mm_set1_pd(fr->ic->k_rf*2.0);
+ crf = _mm_set1_pd(fr->ic->c_rf);
+ /* #endif */
+ /* #endif */
+ /* #if KERNEL_VDW != 'None' */
+ nvdwtype = fr->ntype;
+ vdwparam = fr->nbfp;
+ vdwtype = mdatoms->typeA;
+ /* #endif */
+
+ /* #if 'Table' in KERNEL_ELEC and 'Table' in KERNEL_VDW */
+ vftab = kernel_data->table_elec_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec_vdw->scale);
+ /* #elif 'Table' in KERNEL_ELEC */
+ vftab = kernel_data->table_elec->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_elec->scale);
+ /* #elif 'Table' in KERNEL_VDW */
+ vftab = kernel_data->table_vdw->data;
+ vftabscale = _mm_set1_pd(kernel_data->table_vdw->scale);
+ /* #endif */
+
+ /* #if 'Ewald' in KERNEL_ELEC */
+ sh_ewald = _mm_set1_pd(fr->ic->sh_ewald);
+ /* #if KERNEL_VF=='Force' and KERNEL_MOD_ELEC!='PotentialSwitch' */
+ ewtab = fr->ic->tabq_coul_F;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+ /* #else */
+ ewtab = fr->ic->tabq_coul_FDV0;
+ ewtabscale = _mm_set1_pd(fr->ic->tabq_scale);
+ ewtabhalfspace = _mm_set1_pd(0.5/fr->ic->tabq_scale);
+ /* #endif */
+ /* #endif */
+
+ /* #if KERNEL_ELEC=='GeneralizedBorn' */
+ invsqrta = fr->invsqrta;
+ dvda = fr->dvda;
+ gbtabscale = _mm_set1_pd(fr->gbtab.scale);
+ gbtab = fr->gbtab.data;
+ gbinvepsdiff = _mm_set1_pd((1.0/fr->epsilon_r) - (1.0/fr->gb_epsilon_solvent));
+ /* #endif */
+
+ /* #if 'Water' in GEOMETRY_I */
+ /* Setup water-specific parameters */
+ inr = nlist->iinr[0];
+ /* #for I in PARTICLES_ELEC_I */
+ iq{I} = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+{I}]));
+ /* #endfor */
+ /* #for I in PARTICLES_VDW_I */
+ vdwioffset{I} = 2*nvdwtype*vdwtype[inr+{I}];
+ /* #endfor */
+ /* #endif */
+
+ /* #if 'Water' in GEOMETRY_J */
+ /* #for J in PARTICLES_ELEC_J */
+ jq{J} = _mm_set1_pd(charge[inr+{J}]);
+ /* #endfor */
+ /* #for J in PARTICLES_VDW_J */
+ vdwjidx{J}A = 2*vdwtype[inr+{J}];
+ /* #endfor */
+ /* #for I,J in PAIRS_IJ */
+ /* #if 'electrostatics' in INTERACTION_FLAGS[I][J] */
+ qq{I}{J} = _mm_mul_pd(iq{I},jq{J});
+ /* #endif */
+ /* #if 'vdw' in INTERACTION_FLAGS[I][J] */
+ c6_{I}{J} = _mm_set1_pd(vdwparam[vdwioffset{I}+vdwjidx{J}A]);
+ c12_{I}{J} = _mm_set1_pd(vdwparam[vdwioffset{I}+vdwjidx{J}A+1]);
+ /* #endif */
+ /* #endfor */
+ /* #endif */
+
+ /* #if KERNEL_MOD_ELEC!='None' or KERNEL_MOD_VDW!='None' */
+ /* #if KERNEL_ELEC!='None' */
+ /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
+ rcutoff_scalar = fr->rcoulomb;
+ /* #else */
+ rcutoff_scalar = fr->rvdw;
+ /* #endif */
+ rcutoff = _mm_set1_pd(rcutoff_scalar);
+ rcutoff2 = _mm_mul_pd(rcutoff,rcutoff);
+ /* #endif */
+
+ /* #if KERNEL_MOD_VDW=='PotentialShift' */
+ sh_vdw_invrcut6 = _mm_set1_pd(fr->ic->sh_invrc6);
+ rvdw = _mm_set1_pd(fr->rvdw);
+ /* #endif */
+
+ /* #if 'PotentialSwitch' in [KERNEL_MOD_ELEC,KERNEL_MOD_VDW] */
+ /* #if KERNEL_MOD_ELEC=='PotentialSwitch' */
+ rswitch_scalar = fr->rcoulomb_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* #else */
+ rswitch_scalar = fr->rvdw_switch;
+ rswitch = _mm_set1_pd(rswitch_scalar);
+ /* #endif */
+ /* Setup switch parameters */
+ d_scalar = rcutoff_scalar-rswitch_scalar;
+ d = _mm_set1_pd(d_scalar);
+ swV3 = _mm_set1_pd(-10.0/(d_scalar*d_scalar*d_scalar));
+ swV4 = _mm_set1_pd( 15.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swV5 = _mm_set1_pd( -6.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ /* #if 'Force' in KERNEL_VF */
+ swF2 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar));
+ swF3 = _mm_set1_pd( 60.0/(d_scalar*d_scalar*d_scalar*d_scalar));
+ swF4 = _mm_set1_pd(-30.0/(d_scalar*d_scalar*d_scalar*d_scalar*d_scalar));
+ /* #endif */
+ /* #endif */
+
+ /* Avoid stupid compiler warnings */
+ jnrA = jnrB = 0;
+ j_coord_offsetA = 0;
+ j_coord_offsetB = 0;
+
+ /* ## Keep track of the floating point operations we issue for reporting! */
+ /* #define OUTERFLOPS 0 */
+ outeriter = 0;
+ inneriter = 0;
+
+ /* Start outer loop over neighborlists */
+ for(iidx=0; iidx<nri; iidx++)
+ {
+ /* Load shift vector for this list */
+ i_shift_offset = DIM*shiftidx[iidx];
+
+ /* Load limits for loop over neighbors */
+ j_index_start = jindex[iidx];
+ j_index_end = jindex[iidx+1];
+
+ /* Get outer coordinate index */
+ inr = iinr[iidx];
+ i_coord_offset = DIM*inr;
+
+ /* Load i particle coords and add shift vector */
+ /* #if GEOMETRY_I == 'Particle' */
+ gmx_mm_load_shift_and_1rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,&ix0,&iy0,&iz0);
+ /* #elif GEOMETRY_I == 'Water3' */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
+ /* #elif GEOMETRY_I == 'Water4' */
+ /* #if 0 in PARTICLES_I */
+ gmx_mm_load_shift_and_4rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
+ &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+ /* #else */
+ gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset+DIM,
+ &ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
+ /* #endif */
+ /* #endif */
+
+ /* #if 'Force' in KERNEL_VF */
+ /* #for I in PARTICLES_I */
+ fix{I} = _mm_setzero_pd();
+ fiy{I} = _mm_setzero_pd();
+ fiz{I} = _mm_setzero_pd();
+ /* #endfor */
+ /* #endif */
+
+ /* ## For water we already preloaded parameters at the start of the kernel */
+ /* #if not 'Water' in GEOMETRY_I */
+ /* Load parameters for i particles */
+ /* #for I in PARTICLES_ELEC_I */
+ iq{I} = _mm_mul_pd(facel,_mm_load1_pd(charge+inr+{I}));
+ /* #define OUTERFLOPS OUTERFLOPS+1 */
+ /* #if KERNEL_ELEC=='GeneralizedBorn' */
+ isai{I} = _mm_load1_pd(invsqrta+inr+{I});
+ /* #endif */
+ /* #endfor */
+ /* #for I in PARTICLES_VDW_I */
+ vdwioffset{I} = 2*nvdwtype*vdwtype[inr+{I}];
+ /* #endfor */
+ /* #endif */
+
+ /* #if 'Potential' in KERNEL_VF */
+ /* Reset potential sums */
+ /* #if KERNEL_ELEC != 'None' */
+ velecsum = _mm_setzero_pd();
+ /* #endif */
+ /* #if 'GeneralizedBorn' in KERNEL_ELEC */
+ vgbsum = _mm_setzero_pd();
+ /* #endif */
+ /* #if KERNEL_VDW != 'None' */
+ vvdwsum = _mm_setzero_pd();
+ /* #endif */
+ /* #endif */
+ /* #if 'GeneralizedBorn' in KERNEL_ELEC and 'Force' in KERNEL_VF */
+ dvdasum = _mm_setzero_pd();
+ /* #endif */
+
+ /* #for ROUND in ['Loop','Epilogue'] */
+
+ /* #if ROUND =='Loop' */
+ /* Start inner kernel loop */
+ for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
+ {
+ /* ## First round is normal loop (next statement resets indentation) */
+ /* #if 0 */
+ }
+ /* #endif */
+ /* #else */
+ if(jidx<j_index_end)
+ {
+ /* ## Second round is epilogue */
+ /* #endif */
+ /* #define INNERFLOPS 0 */
+
+ /* #if ROUND =='Loop' */
+ /* Get j neighbor index, and coordinate index */
+ jnrA = jjnr[jidx];
+ jnrB = jjnr[jidx+1];
+ j_coord_offsetA = DIM*jnrA;
+ j_coord_offsetB = DIM*jnrB;
+
+ /* load j atom coordinates */
+ /* #if GEOMETRY_J == 'Particle' */
+ gmx_mm_load_1rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0);
+ /* #elif GEOMETRY_J == 'Water3' */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+ /* #elif GEOMETRY_J == 'Water4' */
+ /* #if 0 in PARTICLES_J */
+ gmx_mm_load_4rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+ /* #else */
+ gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA+DIM,x+j_coord_offsetB+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+ /* #endif */
+ /* #endif */
+ /* #else */
+ jnrA = jjnr[jidx];
+ j_coord_offsetA = DIM*jnrA;
+
+ /* load j atom coordinates */
+ /* #if GEOMETRY_J == 'Particle' */
+ gmx_mm_load_1rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0);
+ /* #elif GEOMETRY_J == 'Water3' */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
+ /* #elif GEOMETRY_J == 'Water4' */
+ /* #if 0 in PARTICLES_J */
+ gmx_mm_load_4rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
+ &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
+ &jy2,&jz2,&jx3,&jy3,&jz3);
+ /* #else */
+ gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA+DIM,
+ &jx1,&jy1,&jz1,&jx2,&jy2,&jz2,&jx3,&jy3,&jz3);
+ /* #endif */
+ /* #endif */
+ /* #endif */
+
+ /* Calculate displacement vector */
+ /* #for I,J in PAIRS_IJ */
+ dx{I}{J} = _mm_sub_pd(ix{I},jx{J});
+ dy{I}{J} = _mm_sub_pd(iy{I},jy{J});
+ dz{I}{J} = _mm_sub_pd(iz{I},jz{J});
+ /* #define INNERFLOPS INNERFLOPS+3 */
+ /* #endfor */
+
+ /* Calculate squared distance and things based on it */
+ /* #for I,J in PAIRS_IJ */
+ rsq{I}{J} = gmx_mm_calc_rsq_pd(dx{I}{J},dy{I}{J},dz{I}{J});
+ /* #define INNERFLOPS INNERFLOPS+5 */
+ /* #endfor */
+
+ /* #for I,J in PAIRS_IJ */
+ /* #if 'rinv' in INTERACTION_FLAGS[I][J] */
+ rinv{I}{J} = gmx_mm_invsqrt_pd(rsq{I}{J});
+ /* #define INNERFLOPS INNERFLOPS+5 */
+ /* #endif */
+ /* #endfor */
+
+ /* #for I,J in PAIRS_IJ */
+ /* #if 'rinvsq' in INTERACTION_FLAGS[I][J] */
+ /* # if 'rinv' not in INTERACTION_FLAGS[I][J] */
+ rinvsq{I}{J} = gmx_mm_inv_pd(rsq{I}{J});
+ /* #define INNERFLOPS INNERFLOPS+4 */
+ /* #else */
+ rinvsq{I}{J} = _mm_mul_pd(rinv{I}{J},rinv{I}{J});
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #endif */
+ /* #endif */
+ /* #endfor */
+
+ /* #if not 'Water' in GEOMETRY_J */
+ /* Load parameters for j particles */
+ /* #for J in PARTICLES_ELEC_J */
+ /* #if ROUND =='Loop' */
+ jq{J} = gmx_mm_load_2real_swizzle_pd(charge+jnrA+{J},charge+jnrB+{J});
+ /* #else */
+ jq{J} = _mm_load_sd(charge+jnrA+{J});
+ /* #endif */
+ /* #if KERNEL_ELEC=='GeneralizedBorn' */
+ /* #if ROUND =='Loop' */
+ isaj{J} = gmx_mm_load_2real_swizzle_pd(invsqrta+jnrA+{J},invsqrta+jnrB+{J});
+ /* #else */
+ isaj{J} = _mm_load_sd(invsqrta+jnrA+{J});
+ /* #endif */
+ /* #endif */
+ /* #endfor */
+ /* #for J in PARTICLES_VDW_J */
+ vdwjidx{J}A = 2*vdwtype[jnrA+{J}];
+ /* #if ROUND =='Loop' */
+ vdwjidx{J}B = 2*vdwtype[jnrB+{J}];
+ /* #endif */
+ /* #endfor */
+ /* #endif */
+
+ /* #if 'Force' in KERNEL_VF and not 'Particle' in GEOMETRY_I */
+ /* #for J in PARTICLES_J */
+ fjx{J} = _mm_setzero_pd();
+ fjy{J} = _mm_setzero_pd();
+ fjz{J} = _mm_setzero_pd();
+ /* #endfor */
+ /* #endif */
+
+ /* #for I,J in PAIRS_IJ */
+
+ /**************************
+ * CALCULATE INTERACTIONS *
+ **************************/
+
+ /* #if 'exactcutoff' in INTERACTION_FLAGS[I][J] */
+ /* ## We always calculate rinv/rinvsq above to enable pipelineing in compilers (performance tested on x86) */
+ if (gmx_mm_any_lt(rsq{I}{J},rcutoff2))
+ {
+ /* #if 0 ## this and the next two lines is a hack to maintain auto-indentation in template file */
+ }
+ /* #endif */
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #endif */
+
+ /* #if 'r' in INTERACTION_FLAGS[I][J] */
+ r{I}{J} = _mm_mul_pd(rsq{I}{J},rinv{I}{J});
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #endif */
+
+ /* ## For water geometries we already loaded parameters at the start of the kernel */
+ /* #if not 'Water' in GEOMETRY_J */
+ /* Compute parameters for interactions between i and j atoms */
+ /* #if 'electrostatics' in INTERACTION_FLAGS[I][J] */
+ qq{I}{J} = _mm_mul_pd(iq{I},jq{J});
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #endif */
+ /* #if 'vdw' in INTERACTION_FLAGS[I][J] */
+ /* #if ROUND == 'Loop' */
+ gmx_mm_load_2pair_swizzle_pd(vdwparam+vdwioffset{I}+vdwjidx{J}A,
+ vdwparam+vdwioffset{I}+vdwjidx{J}B,&c6_{I}{J},&c12_{I}{J});
+ /* #else */
+ gmx_mm_load_1pair_swizzle_pd(vdwparam+vdwioffset{I}+vdwjidx{J}A,&c6_{I}{J},&c12_{I}{J});
+ /* #endif */
+ /* #endif */
+ /* #endif */
+
+ /* #if 'table' in INTERACTION_FLAGS[I][J] */
+ /* Calculate table index by multiplying r with table scale and truncate to integer */
+ rt = _mm_mul_pd(r{I}{J},vftabscale);
+ vfitab = _mm_cvttpd_epi32(rt);
+ vfeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
+ /* #define INNERFLOPS INNERFLOPS+4 */
+ /* #if 'Table' in KERNEL_ELEC and 'Table' in KERNEL_VDW */
+ /* ## 3 tables, 4 data per point: multiply index by 12 */
+ vfitab = _mm_slli_epi32(_mm_add_epi32(vfitab,_mm_slli_epi32(vfitab,1)),2);
+ /* #elif 'Table' in KERNEL_ELEC */
+ /* ## 1 table, 4 data per point: multiply index by 4 */
+ vfitab = _mm_slli_epi32(vfitab,2);
+ /* #elif 'Table' in KERNEL_VDW */
+ /* ## 2 tables, 4 data per point: multiply index by 8 */
+ vfitab = _mm_slli_epi32(vfitab,3);
+ /* #endif */
+ /* #endif */
+
+ /* ## ELECTROSTATIC INTERACTIONS */
+ /* #if 'electrostatics' in INTERACTION_FLAGS[I][J] */
+
+ /* #if KERNEL_ELEC=='Coulomb' */
+
+ /* COULOMB ELECTROSTATICS */
+ velec = _mm_mul_pd(qq{I}{J},rinv{I}{J});
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #if 'Force' in KERNEL_VF */
+ felec = _mm_mul_pd(velec,rinvsq{I}{J});
+ /* #define INNERFLOPS INNERFLOPS+2 */
+ /* #endif */
+
+ /* #elif KERNEL_ELEC=='ReactionField' */
+
+ /* REACTION-FIELD ELECTROSTATICS */
+ /* #if 'Potential' in KERNEL_VF */
+ velec = _mm_mul_pd(qq{I}{J},_mm_sub_pd(_mm_add_pd(rinv{I}{J},_mm_mul_pd(krf,rsq{I}{J})),crf));
+ /* #define INNERFLOPS INNERFLOPS+4 */
+ /* #endif */
+ /* #if 'Force' in KERNEL_VF */
+ felec = _mm_mul_pd(qq{I}{J},_mm_sub_pd(_mm_mul_pd(rinv{I}{J},rinvsq{I}{J}),krf2));
+ /* #define INNERFLOPS INNERFLOPS+3 */
+ /* #endif */
+
+ /* #elif KERNEL_ELEC=='GeneralizedBorn' */
+
+ /* GENERALIZED BORN AND COULOMB ELECTROSTATICS */
+ isaprod = _mm_mul_pd(isai{I},isaj{J});
+ gbqqfactor = _mm_xor_pd(signbit,_mm_mul_pd(qq{I}{J},_mm_mul_pd(isaprod,gbinvepsdiff)));
+ gbscale = _mm_mul_pd(isaprod,gbtabscale);
+ /* #define INNERFLOPS INNERFLOPS+5 */
+
+ /* Calculate generalized born table index - this is a separate table from the normal one,
+ * but we use the same procedure by multiplying r with scale and truncating to integer.
+ */
+ rt = _mm_mul_pd(r{I}{J},gbscale);
+ gbitab = _mm_cvttpd_epi32(rt);
+ gbeps = _mm_sub_pd(rt,_mm_cvtepi32_pd(gbitab));
+ gbitab = _mm_slli_epi32(gbitab,2);
+
+ Y = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) );
+ /* #if ROUND == 'Loop' */
+ F = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,1) );
+ /* #else */
+ F = _mm_setzero_pd();
+ /* #endif */
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,0) +2);
+ /* #if ROUND == 'Loop' */
+ H = _mm_load_pd( gbtab + gmx_mm_extract_epi32(gbitab,1) +2);
+ /* #else */
+ H = _mm_setzero_pd();
+ /* #endif */
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(gbeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(gbeps,_mm_add_pd(G,Heps)));
+ VV = _mm_add_pd(Y,_mm_mul_pd(gbeps,Fp));
+ vgb = _mm_mul_pd(gbqqfactor,VV);
+ /* #define INNERFLOPS INNERFLOPS+10 */
+
+ /* #if 'Force' in KERNEL_VF */
+ FF = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fgb = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
+ dvdatmp = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r{I}{J})));
+ dvdasum = _mm_add_pd(dvdasum,dvdatmp);
+ /* #if ROUND == 'Loop' */
+ gmx_mm_increment_2real_swizzle_pd(dvda+jnrA,dvda+jnrB,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj{J},isaj{J})));
+ /* #else */
+ gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj{J},isaj{J})));
+ /* #endif */
+ /* #define INNERFLOPS INNERFLOPS+13 */
+ /* #endif */
+ velec = _mm_mul_pd(qq{I}{J},rinv{I}{J});
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #if 'Force' in KERNEL_VF */
+ felec = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(velec,rinv{I}{J}),fgb),rinv{I}{J});
+ /* #define INNERFLOPS INNERFLOPS+3 */
+ /* #endif */
+
+ /* #elif KERNEL_ELEC=='Ewald' */
+ /* EWALD ELECTROSTATICS */
+
+ /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
+ ewrt = _mm_mul_pd(r{I}{J},ewtabscale);
+ ewitab = _mm_cvttpd_epi32(ewrt);
+ eweps = _mm_sub_pd(ewrt,_mm_cvtepi32_pd(ewitab));
+ /* #define INNERFLOPS INNERFLOPS+4 */
+ /* #if 'Potential' in KERNEL_VF or KERNEL_MOD_ELEC=='PotentialSwitch' */
+ ewitab = _mm_slli_epi32(ewitab,2);
+ ewtabF = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,0) );
+ /* #if ROUND == 'Loop' */
+ ewtabD = _mm_load_pd( ewtab + gmx_mm_extract_epi32(ewitab,1) );
+ /* #else */
+ ewtabD = _mm_setzero_pd();
+ /* #endif */
+ GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
+ ewtabV = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,0) +2);
+ /* #if ROUND == 'Loop' */
+ ewtabFn = _mm_load_sd( ewtab + gmx_mm_extract_epi32(ewitab,1) +2);
+ /* #else */
+ ewtabFn = _mm_setzero_pd();
+ /* #endif */
+ GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
+ felec = _mm_add_pd(ewtabF,_mm_mul_pd(eweps,ewtabD));
+ /* #define INNERFLOPS INNERFLOPS+2 */
+ /* #if KERNEL_MOD_ELEC=='PotentialShift' */
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq{I}{J},_mm_sub_pd(_mm_sub_pd(rinv{I}{J},sh_ewald),velec));
+ /* #define INNERFLOPS INNERFLOPS+7 */
+ /* #else */
+ velec = _mm_sub_pd(ewtabV,_mm_mul_pd(_mm_mul_pd(ewtabhalfspace,eweps),_mm_add_pd(ewtabF,felec)));
+ velec = _mm_mul_pd(qq{I}{J},_mm_sub_pd(rinv{I}{J},velec));
+ /* #define INNERFLOPS INNERFLOPS+6 */
+ /* #endif */
+ /* #if 'Force' in KERNEL_VF */
+ felec = _mm_mul_pd(_mm_mul_pd(qq{I}{J},rinv{I}{J}),_mm_sub_pd(rinvsq{I}{J},felec));
+ /* #define INNERFLOPS INNERFLOPS+3 */
+ /* #endif */
+ /* #elif KERNEL_VF=='Force' */
+ /* #if ROUND == 'Loop' */
+ gmx_mm_load_2pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),ewtab+gmx_mm_extract_epi32(ewitab,1),
+ &ewtabF,&ewtabFn);
+ /* #else */
+ gmx_mm_load_1pair_swizzle_pd(ewtab+gmx_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
+ /* #endif */
+ felec = _mm_add_pd(_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF),_mm_mul_pd(eweps,ewtabFn));
+ felec = _mm_mul_pd(_mm_mul_pd(qq{I}{J},rinv{I}{J}),_mm_sub_pd(rinvsq{I}{J},felec));
+ /* #define INNERFLOPS INNERFLOPS+7 */
+ /* #endif */
+
+ /* #elif KERNEL_ELEC=='CubicSplineTable' */
+
+ /* CUBIC SPLINE TABLE ELECTROSTATICS */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ /* #if ROUND == 'Loop' */
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ /* #else */
+ F = _mm_setzero_pd();
+ /* #endif */
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ /* #if ROUND == 'Loop' */
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ /* #else */
+ H = _mm_setzero_pd();
+ /* #endif */
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ /* #define INNERFLOPS INNERFLOPS+4 */
+ /* #if 'Potential' in KERNEL_VF */
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ velec = _mm_mul_pd(qq{I}{J},VV);
+ /* #define INNERFLOPS INNERFLOPS+3 */
+ /* #endif */
+ /* #if 'Force' in KERNEL_VF */
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ felec = _mm_xor_pd(signbit,_mm_mul_pd(_mm_mul_pd(qq{I}{J},FF),_mm_mul_pd(vftabscale,rinv{I}{J})));
+ /* #define INNERFLOPS INNERFLOPS+7 */
+ /* #endif */
+ /* #endif */
+ /* ## End of check for electrostatics interaction forms */
+ /* #endif */
+ /* ## END OF ELECTROSTATIC INTERACTION CHECK FOR PAIR I-J */
+
+ /* #if 'vdw' in INTERACTION_FLAGS[I][J] */
+
+ /* #if KERNEL_VDW=='LennardJones' */
+
+ /* LENNARD-JONES DISPERSION/REPULSION */
+
+ rinvsix = _mm_mul_pd(_mm_mul_pd(rinvsq{I}{J},rinvsq{I}{J}),rinvsq{I}{J});
+ /* #define INNERFLOPS INNERFLOPS+2 */
+ /* #if 'Potential' in KERNEL_VF or KERNEL_MOD_VDW=='PotentialSwitch' */
+ vvdw6 = _mm_mul_pd(c6_{I}{J},rinvsix);
+ vvdw12 = _mm_mul_pd(c12_{I}{J},_mm_mul_pd(rinvsix,rinvsix));
+ /* #define INNERFLOPS INNERFLOPS+3 */
+ /* #if KERNEL_MOD_VDW=='PotentialShift' */
+ vvdw = _mm_sub_pd(_mm_mul_pd( _mm_sub_pd(vvdw12 , _mm_mul_pd(c12_{I}{J},_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6))), one_twelfth) ,
+ _mm_mul_pd( _mm_sub_pd(vvdw6,_mm_mul_pd(c6_{I}{J},sh_vdw_invrcut6)),one_sixth));
+ /* #define INNERFLOPS INNERFLOPS+8 */
+ /* #else */
+ vvdw = _mm_sub_pd( _mm_mul_pd(vvdw12,one_twelfth) , _mm_mul_pd(vvdw6,one_sixth) );
+ /* #define INNERFLOPS INNERFLOPS+3 */
+ /* #endif */
+ /* ## Check for force inside potential check, i.e. this means we already did the potential part */
+ /* #if 'Force' in KERNEL_VF */
+ fvdw = _mm_mul_pd(_mm_sub_pd(vvdw12,vvdw6),rinvsq{I}{J});
+ /* #define INNERFLOPS INNERFLOPS+2 */
+ /* #endif */
+ /* #elif KERNEL_VF=='Force' */
+ /* ## Force-only LennardJones makes it possible to save 1 flop (they do add up...) */
+ fvdw = _mm_mul_pd(_mm_sub_pd(_mm_mul_pd(c12_{I}{J},rinvsix),c6_{I}{J}),_mm_mul_pd(rinvsix,rinvsq{I}{J}));
+ /* #define INNERFLOPS INNERFLOPS+4 */
+ /* #endif */
+
+ /* #elif KERNEL_VDW=='CubicSplineTable' */
+
+ /* CUBIC SPLINE TABLE DISPERSION */
+ /* #if 'Table' in KERNEL_ELEC */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ /* #endif */
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ /* #if ROUND == 'Loop' */
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ /* #else */
+ F = _mm_setzero_pd();
+ /* #endif */
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ /* #if ROUND == 'Loop' */
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ /* #else */
+ H = _mm_setzero_pd();
+ /* #endif */
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ /* #define INNERFLOPS INNERFLOPS+4 */
+ /* #if 'Potential' in KERNEL_VF */
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw6 = _mm_mul_pd(c6_{I}{J},VV);
+ /* #define INNERFLOPS INNERFLOPS+3 */
+ /* #endif */
+ /* #if 'Force' in KERNEL_VF */
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw6 = _mm_mul_pd(c6_{I}{J},FF);
+ /* #define INNERFLOPS INNERFLOPS+4 */
+ /* #endif */
+
+ /* CUBIC SPLINE TABLE REPULSION */
+ vfitab = _mm_add_epi32(vfitab,ifour);
+ Y = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
+ /* #if ROUND == 'Loop' */
+ F = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
+ /* #else */
+ F = _mm_setzero_pd();
+ /* #endif */
+ GMX_MM_TRANSPOSE2_PD(Y,F);
+ G = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
+ /* #if ROUND == 'Loop' */
+ H = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
+ /* #else */
+ H = _mm_setzero_pd();
+ /* #endif */
+ GMX_MM_TRANSPOSE2_PD(G,H);
+ Heps = _mm_mul_pd(vfeps,H);
+ Fp = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
+ /* #define INNERFLOPS INNERFLOPS+4 */
+ /* #if 'Potential' in KERNEL_VF */
+ VV = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
+ vvdw12 = _mm_mul_pd(c12_{I}{J},VV);
+ /* #define INNERFLOPS INNERFLOPS+3 */
+ /* #endif */
+ /* #if 'Force' in KERNEL_VF */
+ FF = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
+ fvdw12 = _mm_mul_pd(c12_{I}{J},FF);
+ /* #define INNERFLOPS INNERFLOPS+5 */
+ /* #endif */
+ /* #if 'Potential' in KERNEL_VF */
+ vvdw = _mm_add_pd(vvdw12,vvdw6);
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #endif */
+ /* #if 'Force' in KERNEL_VF */
+ fvdw = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv{I}{J})));
+ /* #define INNERFLOPS INNERFLOPS+4 */
+ /* #endif */
+ /* #endif */
+ /* ## End of check for vdw interaction forms */
+ /* #endif */
+ /* ## END OF VDW INTERACTION CHECK FOR PAIR I-J */
+
+ /* #if 'switch' in INTERACTION_FLAGS[I][J] */
+ d = _mm_sub_pd(r{I}{J},rswitch);
+ d = _mm_max_pd(d,_mm_setzero_pd());
+ d2 = _mm_mul_pd(d,d);
+ sw = _mm_add_pd(one,_mm_mul_pd(d2,_mm_mul_pd(d,_mm_add_pd(swV3,_mm_mul_pd(d,_mm_add_pd(swV4,_mm_mul_pd(d,swV5)))))));
+ /* #define INNERFLOPS INNERFLOPS+10 */
+
+ /* #if 'Force' in KERNEL_VF */
+ dsw = _mm_mul_pd(d2,_mm_add_pd(swF2,_mm_mul_pd(d,_mm_add_pd(swF3,_mm_mul_pd(d,swF4)))));
+ /* #define INNERFLOPS INNERFLOPS+5 */
+ /* #endif */
+
+ /* Evaluate switch function */
+ /* #if 'Force' in KERNEL_VF */
+ /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
+ /* #if 'electrostatics' in INTERACTION_FLAGS[I][J] and KERNEL_MOD_ELEC=='PotentialSwitch' */
+ felec = _mm_sub_pd( _mm_mul_pd(felec,sw) , _mm_mul_pd(rinv{I}{J},_mm_mul_pd(velec,dsw)) );
+ /* #define INNERFLOPS INNERFLOPS+4 */
+ /* #endif */
+ /* #if 'vdw' in INTERACTION_FLAGS[I][J] and KERNEL_MOD_VDW=='PotentialSwitch' */
+ fvdw = _mm_sub_pd( _mm_mul_pd(fvdw,sw) , _mm_mul_pd(rinv{I}{J},_mm_mul_pd(vvdw,dsw)) );
+ /* #define INNERFLOPS INNERFLOPS+4 */
+ /* #endif */
+ /* #endif */
+ /* #if 'Potential' in KERNEL_VF */
+ /* #if 'electrostatics' in INTERACTION_FLAGS[I][J] and KERNEL_MOD_ELEC=='PotentialSwitch' */
+ velec = _mm_mul_pd(velec,sw);
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #endif */
+ /* #if 'vdw' in INTERACTION_FLAGS[I][J] and KERNEL_MOD_VDW=='PotentialSwitch' */
+ vvdw = _mm_mul_pd(vvdw,sw);
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #endif */
+ /* #endif */
+ /* #endif */
+ /* #if 'exactcutoff' in INTERACTION_FLAGS[I][J] */
+ cutoff_mask = _mm_cmplt_pd(rsq{I}{J},rcutoff2);
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #endif */
+
+ /* #if 'Potential' in KERNEL_VF */
+ /* Update potential sum for this i atom from the interaction with this j atom. */
+ /* #if 'electrostatics' in INTERACTION_FLAGS[I][J] */
+ /* #if 'exactcutoff' in INTERACTION_FLAGS[I][J] */
+ velec = _mm_and_pd(velec,cutoff_mask);
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #endif */
+ /* #if ROUND == 'Epilogue' */
+ velec = _mm_unpacklo_pd(velec,_mm_setzero_pd());
+ /* #endif */
+ velecsum = _mm_add_pd(velecsum,velec);
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #if KERNEL_ELEC=='GeneralizedBorn' */
+ /* #if 'exactcutoff' in INTERACTION_FLAGS[I][J] */
+ vgb = _mm_and_pd(vgb,cutoff_mask);
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #endif */
+ /* #if ROUND == 'Epilogue' */
+ vgb = _mm_unpacklo_pd(vgb,_mm_setzero_pd());
+ /* #endif */
+ vgbsum = _mm_add_pd(vgbsum,vgb);
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #endif */
+ /* #endif */
+ /* #if 'vdw' in INTERACTION_FLAGS[I][J] */
+ /* #if 'exactcutoff' in INTERACTION_FLAGS[I][J] */
+ vvdw = _mm_and_pd(vvdw,cutoff_mask);
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #endif */
+ /* #if ROUND == 'Epilogue' */
+ vvdw = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
+ /* #endif */
+ vvdwsum = _mm_add_pd(vvdwsum,vvdw);
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #endif */
+ /* #endif */
+
+ /* #if 'Force' in KERNEL_VF */
+
+ /* #if 'electrostatics' in INTERACTION_FLAGS[I][J] and 'vdw' in INTERACTION_FLAGS[I][J] */
+ fscal = _mm_add_pd(felec,fvdw);
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #elif 'electrostatics' in INTERACTION_FLAGS[I][J] */
+ fscal = felec;
+ /* #elif 'vdw' in INTERACTION_FLAGS[I][J] */
+ fscal = fvdw;
+ /* #endif */
+
+ /* #if 'exactcutoff' in INTERACTION_FLAGS[I][J] */
+ fscal = _mm_and_pd(fscal,cutoff_mask);
+ /* #define INNERFLOPS INNERFLOPS+1 */
+ /* #endif */
+
+ /* #if ROUND == 'Epilogue' */
+ fscal = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
+ /* #endif */
+
+ /* Calculate temporary vectorial force */
+ tx = _mm_mul_pd(fscal,dx{I}{J});
+ ty = _mm_mul_pd(fscal,dy{I}{J});
+ tz = _mm_mul_pd(fscal,dz{I}{J});
+
+ /* Update vectorial force */
+ fix{I} = _mm_add_pd(fix{I},tx);
+ fiy{I} = _mm_add_pd(fiy{I},ty);
+ fiz{I} = _mm_add_pd(fiz{I},tz);
+ /* #define INNERFLOPS INNERFLOPS+6 */
+
+ /* #if GEOMETRY_I == 'Particle' */
+ /* #if ROUND == 'Loop' */
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,tx,ty,tz);
+ /* #else */
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,tx,ty,tz);
+ /* #endif */
+ /* #define INNERFLOPS INNERFLOPS+3 */
+ /* #else */
+ fjx{J} = _mm_add_pd(fjx{J},tx);
+ fjy{J} = _mm_add_pd(fjy{J},ty);
+ fjz{J} = _mm_add_pd(fjz{J},tz);
+ /* #define INNERFLOPS INNERFLOPS+3 */
+ /* #endif */
+
+ /* #endif */
+
+ /* #if 'exactcutoff' in INTERACTION_FLAGS[I][J] */
+ /* #if 0 ## This and next two lines is a hack to maintain indentation in template file */
+ {
+ /* #endif */
+ }
+ /* #endif */
+ /* ## End of check for the interaction being outside the cutoff */
+
+ /* #endfor */
+ /* ## End of loop over i-j interaction pairs */
+
+ /* #if 'Water' in GEOMETRY_I and GEOMETRY_J == 'Particle' */
+ /* #if ROUND == 'Loop' */
+ gmx_mm_decrement_1rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0);
+ /* #else */
+ gmx_mm_decrement_1rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0);
+ /* #endif */
+ /* #define INNERFLOPS INNERFLOPS+3 */
+ /* #elif GEOMETRY_J == 'Water3' */
+ /* #if ROUND == 'Loop' */
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+ /* #else */
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
+ /* #endif */
+ /* #define INNERFLOPS INNERFLOPS+9 */
+ /* #elif GEOMETRY_J == 'Water4' */
+ /* #if 0 in PARTICLES_J */
+ /* #if ROUND == 'Loop' */
+ gmx_mm_decrement_4rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+ /* #else */
+ gmx_mm_decrement_4rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+ /* #endif */
+ /* #define INNERFLOPS INNERFLOPS+12 */
+ /* #else */
+ /* #if ROUND == 'Loop' */
+ gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA+DIM,f+j_coord_offsetB+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+ /* #else */
+ gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA+DIM,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
+ /* #endif */
+ /* #define INNERFLOPS INNERFLOPS+9 */
+ /* #endif */
+ /* #endif */
+
+ /* Inner loop uses {INNERFLOPS} flops */
+ }
+
+ /* #endfor */
+
+ /* End of innermost loop */
+
+ /* #if 'Force' in KERNEL_VF */
+ /* #if GEOMETRY_I == 'Particle' */
+ gmx_mm_update_iforce_1atom_swizzle_pd(fix0,fiy0,fiz0,
+ f+i_coord_offset,fshift+i_shift_offset);
+ /* #define OUTERFLOPS OUTERFLOPS+6 */
+ /* #elif GEOMETRY_I == 'Water3' */
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
+ f+i_coord_offset,fshift+i_shift_offset);
+ /* #define OUTERFLOPS OUTERFLOPS+18 */
+ /* #elif GEOMETRY_I == 'Water4' */
+ /* #if 0 in PARTICLES_I */
+ gmx_mm_update_iforce_4atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset,fshift+i_shift_offset);
+ /* #define OUTERFLOPS OUTERFLOPS+24 */
+ /* #else */
+ gmx_mm_update_iforce_3atom_swizzle_pd(fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
+ f+i_coord_offset+DIM,fshift+i_shift_offset);
+ /* #define OUTERFLOPS OUTERFLOPS+18 */
+ /* #endif */
+ /* #endif */
+ /* #endif */
+
+ /* #if 'Potential' in KERNEL_VF */
+ ggid = gid[iidx];
+ /* Update potential energies */
+ /* #if KERNEL_ELEC != 'None' */
+ gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
+ /* #define OUTERFLOPS OUTERFLOPS+1 */
+ /* #endif */
+ /* #if 'GeneralizedBorn' in KERNEL_ELEC */
+ gmx_mm_update_1pot_pd(vgbsum,kernel_data->energygrp_polarization+ggid);
+ /* #define OUTERFLOPS OUTERFLOPS+1 */
+ /* #endif */
+ /* #if KERNEL_VDW != 'None' */
+ gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
+ /* #define OUTERFLOPS OUTERFLOPS+1 */
+ /* #endif */
+ /* #endif */
+ /* #if 'GeneralizedBorn' in KERNEL_ELEC and 'Force' in KERNEL_VF */
+ dvdasum = _mm_mul_pd(dvdasum, _mm_mul_pd(isai{I},isai{I}));
+ gmx_mm_update_1pot_pd(dvdasum,dvda+inr);
+ /* #endif */
+
+ /* Increment number of inner iterations */
+ inneriter += j_index_end - j_index_start;
+
+ /* Outer loop uses {OUTERFLOPS} flops */
+ }
+
+ /* Increment number of outer iterations */
+ outeriter += nri;
+
+ /* Update outer/inner flops */
+ /* ## NB: This is not important, it just affects the flopcount. However, since our preprocessor is */
+ /* ## primitive and replaces aggressively even in strings inside these directives, we need to */
+ /* ## assemble the main part of the name (containing KERNEL/ELEC/VDW) directly in the source. */
+ /* #if GEOMETRY_I == 'Water3' */
+ /* #define ISUFFIX '_W3' */
+ /* #elif GEOMETRY_I == 'Water4' */
+ /* #define ISUFFIX '_W4' */
+ /* #else */
+ /* #define ISUFFIX '' */
+ /* #endif */
+ /* #if GEOMETRY_J == 'Water3' */
+ /* #define JSUFFIX 'W3' */
+ /* #elif GEOMETRY_J == 'Water4' */
+ /* #define JSUFFIX 'W4' */
+ /* #else */
+ /* #define JSUFFIX '' */
+ /* #endif */
+ /* #if 'PotentialAndForce' in KERNEL_VF */
+ /* #define VFSUFFIX '_VF' */
+ /* #elif 'Potential' in KERNEL_VF */
+ /* #define VFSUFFIX '_V' */
+ /* #else */
+ /* #define VFSUFFIX '_F' */
+ /* #endif */
+
+ /* #if KERNEL_ELEC != 'None' and KERNEL_VDW != 'None' */
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW{ISUFFIX}{JSUFFIX}{VFSUFFIX},outeriter*{OUTERFLOPS} + inneriter*{INNERFLOPS});
+ /* #elif KERNEL_ELEC != 'None' */
+ inc_nrnb(nrnb,eNR_NBKERNEL_ELEC{ISUFFIX}{JSUFFIX}{VFSUFFIX},outeriter*{OUTERFLOPS} + inneriter*{INNERFLOPS});
+ /* #else */
+ inc_nrnb(nrnb,eNR_NBKERNEL_VDW{ISUFFIX}{JSUFFIX}{VFSUFFIX},outeriter*{OUTERFLOPS} + inneriter*{INNERFLOPS});
+ /* #endif */
+}
#if (defined GMX_CPU_ACCELERATION_X86_AVX_256) && !(defined GMX_DOUBLE)
# include "nb_kernel_avx_256_single/nb_kernel_avx_256_single.h"
#endif
-
+#if (defined GMX_CPU_ACCELERATION_X86_SSE2 && defined GMX_DOUBLE)
+# include "nb_kernel_sse2_double/nb_kernel_sse2_double.h"
+#endif
#ifdef GMX_THREAD_MPI
static tMPI_Thread_mutex_t nonbonded_setup_mutex = TMPI_THREAD_MUTEX_INITIALIZER;
if(!(fr!=NULL && fr->use_cpu_acceleration==FALSE))
{
/* Add interaction-specific kernels for different architectures */
+ /* Single precision */
#if (defined GMX_CPU_ACCELERATION_X86_SSE2) && !(defined GMX_DOUBLE)
nb_kernel_list_add_kernels(kernellist_sse2_single,kernellist_sse2_single_size);
#endif
#endif
#if (defined GMX_CPU_ACCELERATION_X86_AVX_256) && !(defined GMX_DOUBLE)
nb_kernel_list_add_kernels(kernellist_avx_256_single,kernellist_avx_256_single_size);
+#endif
+ /* Double precision */
+#if (defined GMX_CPU_ACCELERATION_X86_SSE2 && defined GMX_DOUBLE)
+ nb_kernel_list_add_kernels(kernellist_sse2_double,kernellist_sse2_double_size);
#endif
; /* empty statement to avoid a completely empty block */
}
}
arch_and_padding[] =
{
+ /* Single precision */
#if (defined GMX_CPU_ACCELERATION_X86_AVX_256) && !(defined GMX_DOUBLE)
{ "avx_256_single", 8 },
#endif
#endif
#if (defined GMX_CPU_ACCELERATION_X86_SSE2) && !(defined GMX_DOUBLE)
{ "sse2_single", 4 },
+#endif
+ /* Double precision */
+#if (defined GMX_CPU_ACCELERATION_X86_SSE2 && defined GMX_DOUBLE)
+ /* Sic. Double precision SSE2 does not require neighbor list padding,
+ * since the kernels execute a loop unrolled a factor 2, followed by
+ * a possible single odd-element epilogue.
+ */
+ { "sse2_double", 1 },
#endif
{ "c", 1 },
};