// File: /workspace/github_c_makefile_star2_O2/josch[P]stride/geometry.c
// Function: Torsion
float Torsion(float *Coord1, float *Coord2, float *Coord3, float *Coord4)
{
  double Comp[3][3], ScalarProd, TripleScalarProd, AbsTorsAng;
  double Perp_123[3], Perp_234[3], Len_Perp_123, Len_Perp_234;
  int i, j, k;

  /* Find the components of the three bond vectors */
  for( i=0; i<3; i++ ) {
    Comp[0][i] = (double)(Coord2[i]-Coord1[i]);
    Comp[1][i] = (double)(Coord3[i]-Coord2[i]);
    Comp[2][i] = (double)(Coord4[i]-Coord3[i]);
  }

  /* Calculate vectors perpendicular to the planes 123 and 234 */
  Len_Perp_123 = 0.0; Len_Perp_234 = 0.0;
  for( i=0; i<3; i++ ) {
    j = (i+1)%3;
    k = (j+1)%3;
    Perp_123[i] = Comp[0][j]*Comp[1][k] - Comp[0][k]*Comp[1][j];
    Perp_234[i] = Comp[1][j]*Comp[2][k] - Comp[1][k]*Comp[2][j];
    Len_Perp_123 += Perp_123[i]*Perp_123[i];
    Len_Perp_234 += Perp_234[i]*Perp_234[i];
  }
  
  Len_Perp_123 = sqrt(Len_Perp_123);
  Len_Perp_234 = sqrt(Len_Perp_234);

  /* Normalize the vectors perpendicular to 123 and 234 */
  for( i=0; i<3; i++ ) {
    Perp_123[i] /= Len_Perp_123;
    Perp_234[i] /= Len_Perp_234;
  }

  /* Find the scalar product of the unit normals */
  ScalarProd = 0.0;
  for( i=0; i<3; i++ ) 
    ScalarProd += Perp_123[i]*Perp_234[i];

  /* Find the absolute value of the torsion angle */
  if( ScalarProd > 0.0 && fabs(ScalarProd - 1.0) < Eps ) 
    ScalarProd -= Eps;
  else
  if( ScalarProd < 0.0 && fabs(ScalarProd + 1.0) < Eps ) 
    ScalarProd += Eps;
  AbsTorsAng = RADDEG*acos(ScalarProd);

  /* Find the triple scalar product of the three bond vectors */
  TripleScalarProd = 0.0;
  for( i=0; i<3; i++ ) 
    TripleScalarProd += Comp[0][i]*Perp_234[i];

  /* Torsion angle has the sign of the triple scalar product */
  return( (TripleScalarProd > 0.0) ? (float)AbsTorsAng : (float)(-AbsTorsAng) );

}

// Assembly:
subq $0x98, %rsp
xorl %eax, %eax
cmpq $0xc, %rax
je 0x38ec
movss (%rsi,%rax), %xmm0
movaps %xmm0, %xmm1
subss (%rdi,%rax), %xmm1
cvtss2sd %xmm1, %xmm1
movsd %xmm1, 0x50(%rsp,%rax,2)
movss (%rdx,%rax), %xmm1
movaps %xmm1, %xmm2
subss %xmm0, %xmm2
cvtss2sd %xmm2, %xmm0
movsd %xmm0, 0x68(%rsp,%rax,2)
movss (%rcx,%rax), %xmm0
subss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x80(%rsp,%rax,2)
addq $0x4, %rax
jmp 0x389d
xorpd %xmm4, %xmm4
xorl %eax, %eax
xorl %ecx, %ecx
cmpq $0x3, %rcx
je 0x3971
leaq 0x1(%rcx), %rdx
cmpq $0x2, %rcx
movl %edx, %esi
cmovel %eax, %esi
leal 0x1(%rsi), %edi
leal -0x2(%rsi), %r8d
cmpl $0x3, %edi
cmovbl %edi, %r8d
movl %esi, %esi
movsd 0x50(%rsp,%r8,8), %xmm0
movsd 0x68(%rsp,%r8,8), %xmm1
unpcklpd %xmm1, %xmm0            # xmm0 = xmm0[0],xmm1[0]
movsd 0x50(%rsp,%rsi,8), %xmm2
movsd 0x68(%rsp,%rsi,8), %xmm3
unpcklpd %xmm3, %xmm2            # xmm2 = xmm2[0],xmm3[0]
movhpd 0x80(%rsp,%rsi,8), %xmm3 # xmm3 = xmm3[0],mem[0]
movhpd 0x80(%rsp,%r8,8), %xmm1 # xmm1 = xmm1[0],mem[0]
mulpd %xmm0, %xmm3
mulpd %xmm2, %xmm1
subpd %xmm3, %xmm1
movlpd %xmm1, 0x30(%rsp,%rcx,8)
movhpd %xmm1, 0x10(%rsp,%rcx,8)
mulpd %xmm1, %xmm1
addpd %xmm1, %xmm4
movq %rdx, %rcx
jmp 0x38f4
xorps %xmm0, %xmm0
ucomisd %xmm0, %xmm4
jb 0x3980
sqrtsd %xmm4, %xmm2
jmp 0x399b
movapd %xmm4, %xmm0
movapd %xmm4, (%rsp)
callq 0x2260
movapd (%rsp), %xmm4
movapd %xmm0, %xmm2
xorpd %xmm0, %xmm0
unpckhpd %xmm4, %xmm4            # xmm4 = xmm4[1,1]
ucomisd %xmm0, %xmm4
jb 0x39ab
sqrtsd %xmm4, %xmm0
jmp 0x39be
movapd %xmm4, %xmm0
movsd %xmm2, (%rsp)
callq 0x2260
movsd (%rsp), %xmm2
xorl %eax, %eax
cmpq $0x3, %rax
je 0x39eb
movsd 0x30(%rsp,%rax,8), %xmm1
divsd %xmm2, %xmm1
movsd %xmm1, 0x30(%rsp,%rax,8)
movsd 0x10(%rsp,%rax,8), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, 0x10(%rsp,%rax,8)
incq %rax
jmp 0x39c0
xorpd %xmm0, %xmm0
xorl %eax, %eax
cmpq $0x3, %rax
je 0x3a0c
movsd 0x30(%rsp,%rax,8), %xmm1
mulsd 0x10(%rsp,%rax,8), %xmm1
addsd %xmm1, %xmm0
incq %rax
jmp 0x39f1
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x3a41
movsd 0x14e3b(%rip), %xmm2    # 0x18858
addsd %xmm0, %xmm2
andpd 0x14e97(%rip), %xmm2    # 0x188c0
movsd 0x14e2f(%rip), %xmm3    # 0x18860
ucomisd %xmm2, %xmm3
jbe 0x3a41
addsd 0x14e31(%rip), %xmm0    # 0x18870
jmp 0x3a71
ucomisd %xmm0, %xmm1
jbe 0x3a71
movsd 0x14e19(%rip), %xmm1    # 0x18868
addsd %xmm0, %xmm1
andpd 0x14e65(%rip), %xmm1    # 0x188c0
movsd 0x14dfd(%rip), %xmm2    # 0x18860
ucomisd %xmm1, %xmm2
jbe 0x3a71
addsd 0x14def(%rip), %xmm0    # 0x18860
callq 0x2120
xorpd %xmm1, %xmm1
xorl %eax, %eax
cmpq $0x3, %rax
je 0x3a97
movsd 0x50(%rsp,%rax,8), %xmm2
mulsd 0x10(%rsp,%rax,8), %xmm2
addsd %xmm2, %xmm1
incq %rax
jmp 0x3a7c
mulsd 0x14dd9(%rip), %xmm0    # 0x18878
xorpd %xmm2, %xmm2
ucomisd %xmm2, %xmm1
cvtsd2ss %xmm0, %xmm0
ja 0x3ab4
xorps 0x14e1c(%rip), %xmm0    # 0x188d0
addq $0x98, %rsp
retq