// File: /workspace/github_cpp_makefile_star2_O2/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 $0x48, %rsp
xorl %eax, %eax
movabsq $0x3ff0000000000000, %r10 # imm = 0x3FF0000000000000
movq %rdx, %r8
cmpq $0x3, %rax
je 0x78cfc
xorl %r9d, %r9d
cmpq $0x3, %r9
je 0x78ce8
andq $0x0, (%r8,%r9,8)
incq %r9
jmp 0x78cd8
imulq $0x18, %rax, %r9
addq %rdx, %r9
movq %r10, (%r9,%rax,8)
incq %rax
addq $0x18, %r8
jmp 0x78ccf
xorl %eax, %eax
cmpq $0x18, %rax
je 0x78d1a
movsd (%rdi,%rax,4), %xmm0
movsd %xmm0, (%rsi,%rax)
movsd %xmm0, 0x30(%rsp,%rax)
addq $0x8, %rax
jmp 0x78cfe
xorl %eax, %eax
cmpq $0x3, %rax
je 0x78d2c
andq $0x0, (%rsp,%rax,8)
incq %rax
jmp 0x78d1c
andl $0x0, (%rcx)
leaq 0x8(%rdx), %rax
movq %rax, 0x18(%rsp)
xorl %r9d, %r9d
xorpd %xmm0, %xmm0
movsd 0x8ca29(%rip), %xmm1    # 0x105770
movsd 0x832c1(%rip), %xmm2    # 0xfc010
pushq $0x1
popq %r10
movapd 0x83345(%rip), %xmm3    # 0xfc0a0
movsd 0x832dd(%rip), %xmm4    # 0xfc040
movsd 0x832ed(%rip), %xmm5    # 0xfc058
movapd 0x8785d(%rip), %xmm6    # 0x1005d0
pushq $0x2
popq %r11
movsd 0x832b9(%rip), %xmm7    # 0xfc038
xorl %ebx, %ebx
movq %rdx, 0x20(%rsp)
cmpl $0x32, %ebx
je 0x79148
xorpd %xmm8, %xmm8
movq %rdi, %rax
xorl %r15d, %r15d
cmpq $0x2, %r15
je 0x78dcb
movq %r10, %r8
leaq (%r15,%r8), %r14
cmpq $0x3, %r14
je 0x78dc2
movsd (%rax,%r8,8), %xmm9
andpd %xmm3, %xmm9
addsd %xmm9, %xmm8
incq %r8
jmp 0x78da3
incq %r15
addq $0x20, %rax
jmp 0x78d9a
ucomisd %xmm0, %xmm8
jne 0x78dd8
jnp 0x79158
mulsd %xmm1, %xmm8
divsd %xmm2, %xmm8
cmpl $0x3, %ebx
jb 0x78dec
xorpd %xmm8, %xmm8
movq 0x18(%rsp), %r14
movq %rdx, %r15
xorl %r13d, %r13d
movq %r10, %rax
cmpq $0x2, %r13
je 0x79110
leaq 0x1(%r13), %rbp
imulq $0x18, %r13, %r8
addq %rdi, %r8
movq %r14, 0x28(%rsp)
movq %rax, %r12
cmpq $0x3, %r12
je 0x790f8
leaq (%r8,%r12,8), %rdx
movsd (%rdx), %xmm11
movapd %xmm11, %xmm10
andpd %xmm3, %xmm10
movapd %xmm10, %xmm9
mulsd %xmm4, %xmm9
cmpl $0x4, %ebx
jb 0x78e88
movsd (%rsi,%r13,8), %xmm12
andpd %xmm3, %xmm12
movapd %xmm9, %xmm13
addsd %xmm12, %xmm13
ucomisd %xmm12, %xmm13
jne 0x78e88
jp 0x78e88
movsd (%rsi,%r12,8), %xmm12
andpd %xmm3, %xmm12
movapd %xmm9, %xmm13
addsd %xmm12, %xmm13
ucomisd %xmm12, %xmm13
jne 0x78e88
jp 0x78e88
andq $0x0, (%rdx)
jmp 0x790ec
ucomisd %xmm8, %xmm10
jbe 0x790ec
movsd (%rsi,%r12,8), %xmm10
movsd (%rsi,%r13,8), %xmm12
subsd %xmm12, %xmm10
movapd %xmm10, %xmm13
andpd %xmm3, %xmm13
addsd %xmm13, %xmm9
ucomisd %xmm13, %xmm9
jne 0x78ec8
jp 0x78ec8
movapd %xmm11, %xmm13
divsd %xmm10, %xmm13
jmp 0x78f06
mulsd %xmm7, %xmm10
divsd %xmm11, %xmm10
movapd %xmm10, %xmm9
andpd %xmm3, %xmm9
ucomisd %xmm10, %xmm0
mulsd %xmm10, %xmm10
addsd %xmm5, %xmm10
sqrtsd %xmm10, %xmm10
addsd %xmm9, %xmm10
movapd %xmm5, %xmm13
divsd %xmm10, %xmm13
jbe 0x78f06
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 (%rsp,%r13,8), %xmm13
subsd %xmm11, %xmm13
movsd %xmm13, (%rsp,%r13,8)
movsd (%rsp,%r12,8), %xmm13
addsd %xmm11, %xmm13
movsd %xmm13, (%rsp,%r12,8)
subsd %xmm11, %xmm12
movsd %xmm12, (%rsi,%r13,8)
addsd (%rsi,%r12,8), %xmm11
movsd %xmm11, (%rsi,%r12,8)
andq $0x0, (%rdx)
divsd %xmm14, %xmm10
movapd %xmm9, %xmm11
xorpd %xmm6, %xmm11
xorl %edx, %edx
cmpq %r13, %rdx
jae 0x78fdf
movsd (%rdi,%r13,8), %xmm12
movsd (%rdi,%r12,8), %xmm13
movapd %xmm12, %xmm14
mulsd %xmm10, %xmm14
addsd %xmm13, %xmm14
mulsd %xmm11, %xmm14
addsd %xmm12, %xmm14
movsd %xmm14, (%rdi,%r13,8)
movapd %xmm13, %xmm14
mulsd %xmm10, %xmm14
subsd %xmm14, %xmm12
mulsd %xmm9, %xmm12
addsd %xmm13, %xmm12
movsd %xmm12, (%rdi,%r12,8)
movq %r10, %rdx
jmp 0x78f8b
movq %rbp, %rdx
cmpq %r12, %rdx
jae 0x79038
movsd 0x8(%r8), %xmm12
movsd 0x18(%rdi,%r12,8), %xmm13
movapd %xmm12, %xmm14
mulsd %xmm10, %xmm14
addsd %xmm13, %xmm14
mulsd %xmm11, %xmm14
addsd %xmm12, %xmm14
movsd %xmm14, 0x8(%r8)
movapd %xmm13, %xmm14
mulsd %xmm10, %xmm14
subsd %xmm14, %xmm12
mulsd %xmm9, %xmm12
addsd %xmm13, %xmm12
movsd %xmm12, 0x18(%rdi,%r12,8)
movq %r11, %rdx
jmp 0x78fe2
cmpq $0x2, %r12
je 0x7908e
movsd 0x10(%r8), %xmm12
imulq $0x18, %r12, %rdx
movsd 0x10(%rdi,%rdx), %xmm13
movapd %xmm12, %xmm14
mulsd %xmm10, %xmm14
addsd %xmm13, %xmm14
mulsd %xmm11, %xmm14
addsd %xmm12, %xmm14
movsd %xmm14, 0x10(%r8)
movapd %xmm13, %xmm14
mulsd %xmm10, %xmm14
subsd %xmm14, %xmm12
mulsd %xmm9, %xmm12
addsd %xmm13, %xmm12
movsd %xmm12, 0x10(%rdi,%rdx)
xorl %edx, %edx
cmpq $0x48, %rdx
je 0x790e6
movsd (%r15,%rdx), %xmm12
movsd (%r14,%rdx), %xmm13
movapd %xmm12, %xmm14
mulsd %xmm10, %xmm14
addsd %xmm13, %xmm14
mulsd %xmm11, %xmm14
addsd %xmm12, %xmm14
movsd %xmm14, (%r15,%rdx)
movapd %xmm13, %xmm14
mulsd %xmm10, %xmm14
subsd %xmm14, %xmm12
mulsd %xmm9, %xmm12
addsd %xmm13, %xmm12
movsd %xmm12, (%r14,%rdx)
addq $0x18, %rdx
jmp 0x79090
incl %r9d
movl %r9d, (%rcx)
incq %r12
addq $0x8, %r14
jmp 0x78e17
incq %rax
addq $0x8, %r15
movq 0x28(%rsp), %r14
addq $0x8, %r14
movq %rbp, %r13
jmp 0x78dfa
xorl %eax, %eax
movq 0x20(%rsp), %rdx
cmpq $0x3, %rax
je 0x79141
movsd (%rsp,%rax,8), %xmm8
addsd 0x30(%rsp,%rax,8), %xmm8
movsd %xmm8, 0x30(%rsp,%rax,8)
movsd %xmm8, (%rsi,%rax,8)
andq $0x0, (%rsp,%rax,8)
incq %rax
jmp 0x79117
incl %ebx
jmp 0x78d86
leaq 0x8c661(%rip), %rdi     # 0x1057b0
callq 0x4670
xorl %eax, %eax
jmp 0x7915b
pushq $0x1
popq %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq