// File: /workspace/github_cpp_makefile_star2_O3/Luthaf[P]zeopp/rmsd.cc
// Function: setup_rotation(double (*) [3], double (*) [3], int, double*, double*, double (*) [3], double*)
void setup_rotation(double ref_xlist[][3],
                    double mov_xlist[][3], 
                    int n_list,
                    double mov_com[3],
                    double mov_to_ref[3],
                    double R[3][3],
                    double* E0)
{
  int i, j, n;
  double ref_com[3];

  /* calculate the centre of mass */
  for (i=0; i<3; i++)
  { 
    mov_com[i] = 0.0;
    ref_com[i] = 0.0;
  }
  
  for (n=0; n<n_list; n++) 
    for (i=0; i<3; i++)
    { 
      mov_com[i] += mov_xlist[n][i];
      ref_com[i] += ref_xlist[n][i];
    }
    
  for (i=0; i<3; i++)
  {
    mov_com[i] /= n_list;
    ref_com[i] /= n_list;
    mov_to_ref[i] = ref_com[i] - mov_com[i];
  }

  /* shift mov_xlist and ref_xlist to centre of mass */
  for (n=0; n<n_list; n++) 
    for (i=0; i<3; i++)
    { 
      mov_xlist[n][i] -= mov_com[i];
      ref_xlist[n][i] -= ref_com[i];
    }

  /* initialize */
  for (i=0; i<3; i++)
    for (j=0; j<3; j++) 
      R[i][j] = 0.0;
  *E0 = 0.0;

  for (n=0; n<n_list; n++) 
  {
    /* 
     * E0 = 1/2 * sum(over n): y(n)*y(n) + x(n)*x(n) 
     */
    for (i=0; i<3; i++)
      *E0 +=  mov_xlist[n][i] * mov_xlist[n][i]  
            + ref_xlist[n][i] * ref_xlist[n][i];
    
    /*
     * correlation matrix R:   
     *   R[i,j) = sum(over n): y(n,i) * x(n,j)  
     *   where x(n) and y(n) are two vector sets   
     */
    for (i=0; i<3; i++)
    {
      for (j=0; j<3; j++)
        R[i][j] += mov_xlist[n][i] * ref_xlist[n][j];
    }
  }
  *E0 *= 0.5;
  }

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
xorpd %xmm0, %xmm0
movupd %xmm0, (%rcx)
xorl %eax, %eax
movq %rax, 0x10(%rcx)
movq %rax, -0x10(%rsp)
movapd %xmm0, -0x20(%rsp)
movl %edx, %eax
testl %edx, %edx
jle 0xa16bb
xorl %r10d, %r10d
movq %rsi, %r11
movq %rdi, %rbx
xorl %r14d, %r14d
movsd (%r11,%r14,8), %xmm0
addsd (%rcx,%r14,8), %xmm0
movsd %xmm0, (%rcx,%r14,8)
movsd (%rbx,%r14,8), %xmm0
addsd -0x20(%rsp,%r14,8), %xmm0
movsd %xmm0, -0x20(%rsp,%r14,8)
incq %r14
cmpq $0x3, %r14
jne 0xa167c
incq %r10
addq $0x18, %rbx
addq $0x18, %r11
cmpq %rax, %r10
jne 0xa1679
movq 0x20(%rsp), %r10
xorps %xmm0, %xmm0
cvtsi2sd %edx, %xmm0
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
xorl %r11d, %r11d
movsd -0x20(%rsp,%r11,8), %xmm1
movhpd (%rcx,%r11,8), %xmm1    # xmm1 = xmm1[0],mem[0]
divpd %xmm0, %xmm1
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
movhpd %xmm1, (%rcx,%r11,8)
movlpd %xmm1, -0x20(%rsp,%r11,8)
subsd %xmm2, %xmm1
movsd %xmm1, (%r8,%r11,8)
incq %r11
cmpq $0x3, %r11
jne 0xa16ce
testl %edx, %edx
jle 0xa1820
xorl %r8d, %r8d
movq %rsi, %r11
movq %rdi, %rbx
xorl %r14d, %r14d
movsd (%r11,%r14,8), %xmm0
subsd (%rcx,%r14,8), %xmm0
movsd %xmm0, (%r11,%r14,8)
movsd (%rbx,%r14,8), %xmm0
subsd -0x20(%rsp,%r14,8), %xmm0
movsd %xmm0, (%rbx,%r14,8)
incq %r14
cmpq $0x3, %r14
jne 0xa171b
incq %r8
addq $0x18, %rbx
addq $0x18, %r11
cmpq %rax, %r8
jne 0xa1718
xorl %ecx, %ecx
xorpd %xmm0, %xmm0
movupd %xmm0, 0x30(%r9)
movupd %xmm0, 0x20(%r9)
movupd %xmm0, 0x10(%r9)
movupd %xmm0, (%r9)
movq %rcx, 0x40(%r9)
movq %rcx, (%r10)
testl %edx, %edx
jle 0xa1843
xorl %ecx, %ecx
movq %rsi, %rdx
movsd (%r10), %xmm0
xorl %r8d, %r8d
movsd (%rdx,%r8,8), %xmm1
movsd (%rdi,%r8,8), %xmm2
mulsd %xmm2, %xmm2
mulsd %xmm1, %xmm1
addsd %xmm2, %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, (%r10)
incq %r8
cmpq $0x3, %r8
jne 0xa1792
leaq (%rcx,%rcx,2), %r8
leaq (%rsi,%r8,8), %r8
movq %r9, %r11
xorl %ebx, %ebx
leaq (%r8,%rbx,8), %r14
xorl %r15d, %r15d
movsd (%r14), %xmm0
mulsd (%rdi,%r15,8), %xmm0
addsd (%r11,%r15,8), %xmm0
movsd %xmm0, (%r11,%r15,8)
incq %r15
cmpq $0x3, %r15
jne 0xa17d0
incq %rbx
addq $0x18, %r11
cmpq $0x3, %rbx
jne 0xa17c9
incq %rcx
addq $0x18, %rdi
addq $0x18, %rdx
cmpq %rax, %rcx
jne 0xa178a
movsd (%r10), %xmm0
mulsd 0xab81a(%rip), %xmm0    # 0x14d038
jmp 0xa1847
xorpd %xmm0, %xmm0
movupd %xmm0, 0x30(%r9)
movupd %xmm0, 0x20(%r9)
movupd %xmm0, 0x10(%r9)
movupd %xmm0, (%r9)
movq $0x0, 0x40(%r9)
xorpd %xmm0, %xmm0
movsd %xmm0, (%r10)
popq %rbx
popq %r14
popq %r15
retq