// File: /workspace/github_cpp_makefile_star2_O2/kaityo256[P]lj_simd/force_aos.cpp
// Function: force_avx2()
void
force_avx2(void) {
  const v4df vzero = _mm256_set1_pd(0.0);
  const v4df vcl2 = _mm256_set1_pd(CL2);
  const v4df vc24 = _mm256_set1_pd(24 * dt);
  const v4df vc48 = _mm256_set1_pd(48 * dt);
  const int pn = particle_number;
  for (int i = 0; i < pn; i++) {
    const v4df vqi = _mm256_load_pd((double *)(q + i));
    v4df vpi = _mm256_load_pd((double *)(p + i));
    const int np = number_of_partners[i];
    const int kp = pointer[i];
    for (int k = 0; k < (np / 4) * 4; k += 4) {
      const int j_1 = sorted_list[kp + k];
      const int j_2 = sorted_list[kp + k + 1];
      const int j_3 = sorted_list[kp + k + 2];
      const int j_4 = sorted_list[kp + k + 3];
      v4df vqj_1 = _mm256_load_pd((double *)(q + j_1));
      v4df vqj_2 = _mm256_load_pd((double *)(q + j_2));
      v4df vqj_3 = _mm256_load_pd((double *)(q + j_3));
      v4df vqj_4 = _mm256_load_pd((double *)(q + j_4));

      v4df vdq_1 = (vqj_1 - vqi);
      v4df vdq_2 = (vqj_2 - vqi);
      v4df vdq_3 = (vqj_3 - vqi);
      v4df vdq_4 = (vqj_4 - vqi);

      v4df tmp0 = _mm256_unpacklo_pd(vdq_1, vdq_2);
      v4df tmp1 = _mm256_unpackhi_pd(vdq_1, vdq_2);
      v4df tmp2 = _mm256_unpacklo_pd(vdq_3, vdq_4);
      v4df tmp3 = _mm256_unpackhi_pd(vdq_3, vdq_4);

      v4df vdx = _mm256_permute2f128_pd(tmp0, tmp2, 0x20);
      v4df vdy = _mm256_permute2f128_pd(tmp1, tmp3, 0x20);
      v4df vdz = _mm256_permute2f128_pd(tmp0, tmp2, 0x31);

      v4df vr2 = vdx * vdx + vdy * vdy + vdz * vdz;
      v4df vr6 = vr2 * vr2 * vr2;
      v4df vdf = (vc24 * vr6 - vc48) / (vr6 * vr6 * vr2);
      v4df mask = vcl2 - vr2;
      vdf = _mm256_blendv_pd(vdf, vzero, mask);

      v4df vdf_1 = _mm256_permute4x64_pd(vdf, 0);
      v4df vdf_2 = _mm256_permute4x64_pd(vdf, 85);
      v4df vdf_3 = _mm256_permute4x64_pd(vdf, 170);
      v4df vdf_4 = _mm256_permute4x64_pd(vdf, 255);

      v4df vpj_1 = _mm256_load_pd((double *)(p + j_1));
      v4df vpj_2 = _mm256_load_pd((double *)(p + j_2));
      v4df vpj_3 = _mm256_load_pd((double *)(p + j_3));
      v4df vpj_4 = _mm256_load_pd((double *)(p + j_4));

      vpj_1 -= vdq_1 * vdf_1;
      vpj_2 -= vdq_2 * vdf_2;
      vpj_3 -= vdq_3 * vdf_3;
      vpj_4 -= vdq_4 * vdf_4;

      vpi += vdq_1 * vdf_1;
      vpi += vdq_2 * vdf_2;
      vpi += vdq_3 * vdf_3;
      vpi += vdq_4 * vdf_4;

      _mm256_store_pd((double *)(p + j_1), vpj_1);
      _mm256_store_pd((double *)(p + j_2), vpj_2);
      _mm256_store_pd((double *)(p + j_3), vpj_3);
      _mm256_store_pd((double *)(p + j_4), vpj_4);
    }
    _mm256_store_pd((double *)(p + i), vpi);
    for (int k = (np / 4) * 4; k < np; k++) {
      const int j = sorted_list[kp + k];
      double dx = q[j][X] - q[i][X];
      double dy = q[j][Y] - q[i][Y];
      double dz = q[j][Z] - q[i][Z];
      double r2 = (dx * dx + dy * dy + dz * dz);
      double r6 = r2 * r2 * r2;
      double df = ((24.0 * r6 - 48.0) / (r6 * r6 * r2)) * dt;
      if (r2 > CL2) df = 0.0;
      p[i][X] += df * dx;
      p[i][Y] += df * dy;
      p[i][Z] += df * dz;
      p[j][X] -= df * dx;
      p[j][Y] -= df * dy;
      p[j][Z] -= df * dz;
    }
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
vbroadcastsd 0x1f5b(%rip), %ymm0 # 0x4048
vbroadcastsd 0x1f59(%rip), %ymm21 # 0x4050
vbroadcastsd 0x1f3f(%rip), %ymm22 # 0x4040
vmovsd 0x1f1f(%rip), %xmm4     # 0x4028
vmovsd 0x1f1f(%rip), %xmm5     # 0x4030
vmovsd 0x1f1f(%rip), %xmm6     # 0x4038
vmovsd 0x1f1f(%rip), %xmm7     # 0x4040
movl 0x325ea59(%rip), %eax   # 0x3260b80
leaq 0x18aa22(%rip), %r8     # 0x18cb50
leaq 0xdbfa1b(%rip), %r9     # 0xdc1b50
leaq 0x90f9654(%rip), %r14   # 0x90fb790
vxorpd %xmm3, %xmm3, %xmm3
vxorpd %xmm8, %xmm8, %xmm8
xorl %edi, %edi
movl %eax, %ecx
sarl $0x1f, %ecx
andnl %eax, %ecx, %esi
cmpq %rsi, %rdi
je 0x23cd
leaq 0x325ea2f(%rip), %rax   # 0x3260b90
movq %rdi, %r10
shlq $0x5, %r10
movl $0x4, %r11d
xorl %r13d, %r13d
movslq (%rax,%rdi,4), %rcx
leaq 0x8f72c14(%rip), %rax   # 0x8f74d90
vmovapd (%r10,%r8), %ymm9
vmovapd (%r10,%r9), %ymm11
leaq (%r9,%r10), %r15
movslq (%rax,%rdi,4), %r12
movl %ecx, %eax
cltd
idivl %r11d
vmovsd 0x10(%r10,%r8), %xmm10
leaq 0xc(%r14,%r12,4), %rdx
shll $0x2, %eax
cltq
cmpq %rax, %r13
jge 0x2300
movslq -0xc(%rdx,%r13,4), %rbp
movslq -0x8(%rdx,%r13,4), %r10
movslq -0x4(%rdx,%r13,4), %r11
movslq (%rdx,%r13,4), %rbx
addq $0x4, %r13
shlq $0x5, %rbx
shlq $0x5, %rbp
shlq $0x5, %r10
shlq $0x5, %r11
vmovapd (%rbp,%r8), %ymm12
vmovapd (%r10,%r8), %ymm13
vmovapd (%r11,%r8), %ymm14
vmovapd (%rbx,%r8), %ymm15
vmovapd (%rbx,%r9), %ymm23
vsubpd %ymm9, %ymm12, %ymm12
vsubpd %ymm9, %ymm13, %ymm13
vsubpd %ymm9, %ymm14, %ymm14
vsubpd %ymm9, %ymm15, %ymm15
vinsertf32x4 $0x1, %xmm15, %ymm13, %ymm19
vinsertf32x4 $0x1, %xmm14, %ymm12, %ymm20
vunpcklpd %ymm13, %ymm12, %ymm16 # ymm16 = ymm12[0],ymm13[0],ymm12[2],ymm13[2]
vunpcklpd %ymm15, %ymm14, %ymm17 # ymm17 = ymm14[0],ymm15[0],ymm14[2],ymm15[2]
vinsertf32x4 $0x1, %xmm17, %ymm16, %ymm18
vshuff64x2 $0x3, %ymm17, %ymm16, %ymm16 # ymm16 = ymm16[2,3],ymm17[2,3]
vunpckhpd %ymm19, %ymm20, %ymm19 # ymm19 = ymm20[1],ymm19[1],ymm20[3],ymm19[3]
vmovapd (%r11,%r9), %ymm20
vmulpd %ymm19, %ymm19, %ymm17
vmovapd (%r10,%r9), %ymm19
vfmadd231pd %ymm18, %ymm18, %ymm17 # ymm17 = (ymm18 * ymm18) + ymm17
vmovapd %ymm0, %ymm18
vfmadd231pd %ymm16, %ymm16, %ymm17 # ymm17 = (ymm16 * ymm16) + ymm17
vmulpd %ymm17, %ymm17, %ymm16
vsubpd %ymm17, %ymm22, %ymm2
vmulpd %ymm16, %ymm17, %ymm16
vfmadd213pd %ymm21, %ymm16, %ymm18 # ymm18 = (ymm16 * ymm18) + ymm21
vmulpd %ymm16, %ymm16, %ymm16
vmulpd %ymm16, %ymm17, %ymm16
vdivpd %ymm16, %ymm18, %ymm1
vmovapd (%rbp,%r9), %ymm18
vblendvpd %ymm2, %ymm3, %ymm1, %ymm1
vbroadcastsd %xmm1, %ymm2
vpermpd $0x55, %ymm1, %ymm16    # ymm16 = ymm1[1,1,1,1]
vpermpd $0xaa, %ymm1, %ymm17    # ymm17 = ymm1[2,2,2,2]
vpermpd $0xff, %ymm1, %ymm1     # ymm1 = ymm1[3,3,3,3]
vfmadd231pd %ymm2, %ymm12, %ymm11 # ymm11 = (ymm12 * ymm2) + ymm11
vfnmadd231pd %ymm2, %ymm12, %ymm18 # ymm18 = -(ymm12 * ymm2) + ymm18
vfnmadd231pd %ymm16, %ymm13, %ymm19 # ymm19 = -(ymm13 * ymm16) + ymm19
vfnmadd231pd %ymm17, %ymm14, %ymm20 # ymm20 = -(ymm14 * ymm17) + ymm20
vfnmadd231pd %ymm1, %ymm15, %ymm23 # ymm23 = -(ymm15 * ymm1) + ymm23
vfmadd231pd %ymm16, %ymm13, %ymm11 # ymm11 = (ymm13 * ymm16) + ymm11
vmovapd %ymm18, (%rbp,%r9)
vmovapd %ymm19, (%r10,%r9)
vmovapd %ymm20, (%r11,%r9)
vmovapd %ymm23, (%rbx,%r9)
vfmadd231pd %ymm17, %ymm14, %ymm11 # ymm11 = (ymm14 * ymm17) + ymm11
vfmadd231pd %ymm1, %ymm15, %ymm11 # ymm11 = (ymm15 * ymm1) + ymm11
jmp 0x21a7
addq %rax, %r12
vmovapd %ymm11, (%r15)
leaq (%r14,%r12,4), %rdx
cmpq %rcx, %rax
jge 0x23c5
movslq (%rdx), %r10
vmovapd %xmm4, %xmm13
incq %rax
addq $0x4, %rdx
shlq $0x5, %r10
vmovapd (%r10,%r8), %xmm2
vmovsd 0x10(%r10,%r8), %xmm1
vsubpd %xmm9, %xmm2, %xmm2
vsubsd %xmm10, %xmm1, %xmm1
vmulpd %xmm2, %xmm2, %xmm11
vshufpd $0x1, %xmm11, %xmm11, %xmm11 # xmm11 = xmm11[1,0]
vfmadd231sd %xmm2, %xmm2, %xmm11 # xmm11 = (xmm2 * xmm2) + xmm11
vfmadd231sd %xmm1, %xmm1, %xmm11 # xmm11 = (xmm1 * xmm1) + xmm11
vmulsd %xmm11, %xmm11, %xmm12
vcmpgtsd %xmm7, %xmm11, %k1
vmulsd %xmm12, %xmm11, %xmm12
vfmadd213sd %xmm5, %xmm12, %xmm13 # xmm13 = (xmm12 * xmm13) + xmm5
vmulsd %xmm12, %xmm12, %xmm12
vmulsd %xmm12, %xmm11, %xmm12
vdivsd %xmm12, %xmm13, %xmm12
vmovapd (%r15), %xmm13
vmulsd %xmm6, %xmm12, %xmm12
vmovsd %xmm8, %xmm12, %xmm12 {%k1}
vmovddup %xmm12, %xmm11          # xmm11 = xmm12[0,0]
vfmadd231pd %xmm2, %xmm11, %xmm13 # xmm13 = (xmm11 * xmm2) + xmm13
vmovapd %xmm13, (%r15)
vmovsd 0x10(%r15), %xmm13
vfmadd231sd %xmm1, %xmm12, %xmm13 # xmm13 = (xmm12 * xmm1) + xmm13
vmovsd %xmm13, 0x10(%r15)
vfnmadd213pd (%r10,%r9), %xmm11, %xmm2 # xmm2 = -(xmm11 * xmm2) + mem
vmovapd %xmm2, (%r10,%r9)
vfnmadd213sd 0x10(%r10,%r9), %xmm12, %xmm1 # xmm1 = -(xmm12 * xmm1) + mem
vmovsd %xmm1, 0x10(%r10,%r9)
jmp 0x230c
incq %rdi
jmp 0x2151
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
vzeroupper
retq