// File: /workspace/github_cpp_makefile_star2_O3/Luthaf[P]zeopp/rmsd.cc
// Function: jacobi3(double (*) [3], double*, double (*) [3], int*)
int jacobi3(double a[3][3], double d[3], double v[3][3], int* n_rot)
{
  int count, k, i, j;
  double tresh, theta, tau, t, sum, s, h, g, c, b[3], z[3];

  /*Initialize v to the identity matrix.*/
  for (i=0; i<3; i++) 
  { 
    for (j=0; j<3; j++) 
      v[i][j] = 0.0;
    v[i][i] = 1.0;
  }

  /* Initialize b and d to the diagonal of a */
  for (i=0; i<3; i++) 
    b[i] = d[i] = a[i][i];

  /* z will accumulate terms */
  for (i=0; i<3; i++) 
    z[i] = 0.0; 
  
  *n_rot = 0;

  /* 50 tries */
  for (count=0; count<50; count++)     
  {

    /* sum off-diagonal elements */
    sum = 0.0;
    for (i=0; i<2; i++) 
    {
      for (j=i+1; j<3; j++)
         sum += fabs(a[i][j]);
    }

    /* if converged to machine underflow */
    if (sum == 0.0) 
      return(1);

    /* on 1st three sweeps... */
    if (count < 3) 
      tresh = sum * 0.2 / 9.0;    
    else       
      tresh = 0.0;      

    for (i=0; i<2; i++) 
    {
      for (j=i+1; j<3; j++) 
      {
        g = 100.0 * fabs(a[i][j]);

        /*  after four sweeps, skip the rotation if
         *   the off-diagonal element is small 
         */
        if ( count > 3  &&  fabs(d[i])+g == fabs(d[i])
              &&  fabs(d[j])+g == fabs(d[j]) ) 
        {
          a[i][j] = 0.0;
        } 
        else if (fabs(a[i][j]) > tresh) 
        {
          h = d[j] - d[i];
          
          if (fabs(h)+g == fabs(h))
          {
            t = a[i][j] / h;
          }
          else 
          {
            theta = 0.5 * h / (a[i][j]);
            t = 1.0 / ( fabs(theta) +
                        (double)sqrt(1.0 + theta*theta) );
            if (theta < 0.0) 
              t = -t;
          }
          
          c = 1.0 / (double) sqrt(1 + t*t);
          s = t * c;
          tau = s / (1.0 + c);
          h = t * a[i][j];

          z[i] -= h;
          z[j] += h;
          d[i] -= h;
          d[j] += h;

          a[i][j] = 0.0;

          for (k=0; k<=i-1; k++) 
            ROTATE(a, k, i, k, j)

          for (k=i+1; k<=j-1; k++) 
            ROTATE(a, i, k, k, j)

          for (k=j+1; k<3; k++) 
            ROTATE(a, i, k, j, k)

          for (k=0; k<3; k++) 
            ROTATE(v, k, i, k, j)

          ++(*n_rot);
        }
      }
    }

    for (i=0; i<3; i++) 
    {
      b[i] += z[i];
      d[i] = b[i];
      z[i] = 0.0;
    }
  }

  printf("Too many iterations in jacobi3\n");
  return (0);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
xorl %eax, %eax
xorps %xmm0, %xmm0
movabsq $0x3ff0000000000000, %r9 # imm = 0x3FF0000000000000
movq %rdx, %r8
movups %xmm0, (%rdx,%rax)
movq $0x0, 0x10(%rdx,%rax)
movq %r9, (%r8)
addq $0x20, %r8
addq $0x18, %rax
cmpq $0x48, %rax
jne 0xa1872
xorl %eax, %eax
movsd (%rdi,%rax,4), %xmm0
movsd %xmm0, (%rsi,%rax)
movsd %xmm0, 0x50(%rsp,%rax)
addq $0x8, %rax
cmpq $0x18, %rax
jne 0xa1892
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %rax
movaps %xmm0, (%rax)
movq $0x0, 0x10(%rax)
movl $0x0, (%rcx)
leaq 0x8(%rdi), %r14
leaq 0x8(%rdx), %rax
movq %rax, 0x30(%rsp)
xorl %r11d, %r11d
movapd 0xab7c3(%rip), %xmm0    # 0x14d0a0
xorpd %xmm1, %xmm1
movsd 0xb4fa7(%rip), %xmm2    # 0x156890
movsd 0xab71f(%rip), %xmm3    # 0x14d010
movsd 0xab747(%rip), %xmm4    # 0x14d040
movsd 0xab757(%rip), %xmm5    # 0x14d058
movapd 0xafd37(%rip), %xmm6    # 0x151640
movsd 0xab727(%rip), %xmm7    # 0x14d038
xorl %ebx, %ebx
movq %rdx, 0x40(%rsp)
movq %r14, 0x38(%rsp)
movb $0x1, %r10b
xorl %eax, %eax
xorl %r8d, %r8d
xorpd %xmm8, %xmm8
leaq (%r8,%r8,2), %r8
leaq (%r14,%r8,8), %r8
movq %rax, %r9
movsd (%r8,%r9,8), %xmm9
andpd %xmm0, %xmm9
addsd %xmm9, %xmm8
incq %r9
cmpq $0x2, %r9
jne 0xa1935
incq %rax
movl $0x1, %r8d
testb $0x1, %r10b
movl $0x0, %r10d
jne 0xa192a
ucomisd %xmm1, %xmm8
jne 0xa1970
jnp 0xa1d38
mulsd %xmm2, %xmm8
divsd %xmm3, %xmm8
cmpl $0x3, %ebx
jb 0xa1984
xorpd %xmm8, %xmm8
movl $0x1, %r14d
movb $0x1, %r8b
xorl %r12d, %r12d
movq 0x30(%rsp), %rbp
leaq 0x10(%rsp), %rax
xorl %r13d, %r13d
movl %r8d, 0xc(%rsp)
leaq 0x1(%r13), %r10
leaq (,%r13,2), %r8
addq %r13, %r8
leaq (%rdi,%r8,8), %r8
leaq (%rdx,%r13,8), %r9
movq %rbp, %r15
movq %r14, 0x48(%rsp)
leaq (%r8,%r14,8), %rdx
movsd (%rdx), %xmm11
movapd %xmm11, %xmm10
andpd %xmm0, %xmm10
movapd %xmm10, %xmm9
mulsd %xmm4, %xmm9
cmpl $0x4, %ebx
jb 0xa1a2b
movsd (%rsi,%r13,8), %xmm12
andpd %xmm0, %xmm12
movapd %xmm9, %xmm13
addsd %xmm12, %xmm13
ucomisd %xmm12, %xmm13
jne 0xa1a2b
jp 0xa1a2b
movsd (%rsi,%r14,8), %xmm12
andpd %xmm0, %xmm12
movapd %xmm9, %xmm13
addsd %xmm12, %xmm13
ucomisd %xmm12, %xmm13
jne 0xa1a2b
jp 0xa1a2b
movq $0x0, (%rdx)
jmp 0xa1ca8
ucomisd %xmm8, %xmm10
jbe 0xa1ca8
movsd (%rsi,%r14,8), %xmm10
movsd (%rsi,%r13,8), %xmm12
subsd %xmm12, %xmm10
movapd %xmm10, %xmm13
andpd %xmm0, %xmm13
addsd %xmm13, %xmm9
ucomisd %xmm13, %xmm9
jne 0xa1a6b
jp 0xa1a6b
movapd %xmm11, %xmm13
divsd %xmm10, %xmm13
jmp 0xa1aa9
mulsd %xmm7, %xmm10
divsd %xmm11, %xmm10
movapd %xmm10, %xmm9
andpd %xmm0, %xmm9
ucomisd %xmm10, %xmm1
mulsd %xmm10, %xmm10
addsd %xmm5, %xmm10
sqrtsd %xmm10, %xmm10
addsd %xmm9, %xmm10
movapd %xmm5, %xmm13
divsd %xmm10, %xmm13
jbe 0xa1aa9
xorpd %xmm6, %xmm13
movapd %xmm13, %xmm9
mulsd %xmm13, %xmm9
addsd %xmm5, %xmm9
sqrtsd %xmm9, %xmm9
movapd %xmm5, %xmm14
divsd %xmm9, %xmm14
movapd %xmm13, %xmm9
mulsd %xmm14, %xmm9
addsd %xmm5, %xmm14
movapd %xmm9, %xmm10
mulsd %xmm13, %xmm11
movsd (%rax), %xmm13
subsd %xmm11, %xmm13
movsd %xmm13, (%rax)
movsd 0x10(%rsp,%r14,8), %xmm13
addsd %xmm11, %xmm13
movsd %xmm13, 0x10(%rsp,%r14,8)
subsd %xmm11, %xmm12
movsd %xmm12, (%rsi,%r13,8)
addsd (%rsi,%r14,8), %xmm11
divsd %xmm14, %xmm10
movsd %xmm11, (%rsi,%r14,8)
movq $0x0, (%rdx)
testb $0x1, %r12b
je 0xa1b7a
movsd (%rdi,%r13,8), %xmm11
movsd (%rdi,%r14,8), %xmm12
movapd %xmm11, %xmm13
mulsd %xmm10, %xmm13
addsd %xmm12, %xmm13
mulsd %xmm9, %xmm13
movapd %xmm11, %xmm14
subsd %xmm13, %xmm14
movsd %xmm14, (%rdi,%r13,8)
movapd %xmm12, %xmm13
mulsd %xmm10, %xmm13
subsd %xmm13, %xmm11
mulsd %xmm9, %xmm11
addsd %xmm12, %xmm11
movsd %xmm11, (%rdi,%r14,8)
cmpq %r14, %r10
jae 0xa1bdb
movapd %xmm9, %xmm11
xorpd %xmm6, %xmm11
movsd 0x18(%rdi,%r14,8), %xmm12
movsd 0x8(%r8), %xmm13
movapd %xmm13, %xmm14
mulsd %xmm10, %xmm14
addsd %xmm12, %xmm14
mulsd %xmm11, %xmm14
addsd %xmm13, %xmm14
movsd %xmm14, 0x8(%r8)
movapd %xmm12, %xmm14
mulsd %xmm10, %xmm14
subsd %xmm14, %xmm13
mulsd %xmm9, %xmm13
addsd %xmm13, %xmm12
movsd %xmm12, 0x18(%rdi,%r14,8)
cmpq $0x2, %r14
ja 0xa1b90
cmpq $0x2, %r14
jne 0xa1bed
movapd %xmm9, %xmm11
xorpd %xmm6, %xmm11
jmp 0xa1c4c
movsd 0x10(%r8), %xmm12
leaq (%r14,%r14,2), %rdx
movsd 0x10(%rdi,%rdx,8), %xmm13
movapd %xmm12, %xmm14
mulsd %xmm10, %xmm14
addsd %xmm13, %xmm14
movapd %xmm9, %xmm11
xorpd %xmm6, %xmm11
mulsd %xmm9, %xmm14
movapd %xmm12, %xmm15
subsd %xmm14, %xmm15
movsd %xmm15, 0x10(%r8)
movapd %xmm13, %xmm14
mulsd %xmm10, %xmm14
subsd %xmm14, %xmm12
mulsd %xmm9, %xmm12
addsd %xmm13, %xmm12
movsd %xmm12, 0x10(%rdi,%rdx,8)
xorl %edx, %edx
movsd (%r9,%rdx), %xmm12
movsd (%r15,%rdx), %xmm13
movapd %xmm12, %xmm14
mulsd %xmm10, %xmm14
addsd %xmm13, %xmm14
mulsd %xmm11, %xmm14
addsd %xmm12, %xmm14
movsd %xmm14, (%r9,%rdx)
movapd %xmm13, %xmm14
mulsd %xmm10, %xmm14
subsd %xmm14, %xmm12
mulsd %xmm9, %xmm12
addsd %xmm13, %xmm12
movsd %xmm12, (%r15,%rdx)
addq $0x18, %rdx
cmpq $0x48, %rdx
jne 0xa1c4e
incl %r11d
movl %r11d, (%rcx)
incq %r14
addq $0x8, %r15
cmpq $0x3, %r14
jne 0xa19c1
movq 0x48(%rsp), %r14
incq %r14
addq $0x8, %rbp
movl $0x1, %r13d
movb $0x1, %r12b
leaq 0x18(%rsp), %rax
testb $0x1, 0xc(%rsp)
movl $0x0, %r8d
movq 0x40(%rsp), %rdx
jne 0xa199d
xorl %eax, %eax
movsd 0x10(%rsp,%rax,8), %xmm8
addsd 0x50(%rsp,%rax,8), %xmm8
movsd %xmm8, 0x50(%rsp,%rax,8)
movsd %xmm8, (%rsi,%rax,8)
movq $0x0, 0x10(%rsp,%rax,8)
incq %rax
cmpq $0x3, %rax
jne 0xa1ceb
incl %ebx
cmpl $0x32, %ebx
movq 0x38(%rsp), %r14
jne 0xa191d
leaq 0xb4ba1(%rip), %rdi     # 0x1568d0
callq 0x4660
xorl %eax, %eax
jmp 0xa1d3d
movl $0x1, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq