// File: Luthaf[P]zeopp/geometry.cc
// Function: RotatePointAboutLine(XYZ, double, XYZ, XYZ)
XYZ RotatePointAboutLine(XYZ p, double theta, XYZ p1, XYZ p2) {
  XYZ u, q1, q2;
  double d;
  // Step 1
  q1 = p - p1;
  u = (p2 - p1).unit();
  d = sqrt(u.y*u.y + u.z*u.z);
  // Step 2
  if (d!=0) {
    q2.x = q1.x;
    q2.y = q1.y * u.z / d - q1.z * u.y / d;
    q2.z = q1.y * u.y / d + q1.z * u.z / d;
  } else {
    q2 = q1;
  }
  // Step 3
  q1.x = q2.x * d - q2.z * u.x;
  q1.y = q2.y;
  q1.z = q2.x * u.x + q2.z * d;
  // Step 4
  q2.x = q1.x * cos(theta) - q1.y * sin(theta);
  q2.y = q1.x * sin(theta) + q1.y * cos(theta);
  q2.z = q1.z;
  // Inverse of step 3
  q1.x = q2.x * d + q2.z * u.x;
  q1.y = q2.y;
  q1.z = - q2.x * u.x + q2.z * d;
  // Inverse of step 2
  if (d!=0) {
    q2.x =   q1.x;
    q2.y =   q1.y * u.z / d + q1.z * u.y / d;
    q2.z = - q1.y * u.y / d + q1.z * u.z / d;
  } else {
    q2 = q1;
  }
  // Inverse of step 1
  q1 = q2 + p1;
  return(q1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movq %rdi, -0xb8(%rbp)
movq %rdi, -0xc8(%rbp)
leaq 0x40(%rbp), %rax
movq %rax, -0xb0(%rbp)
leaq 0x28(%rbp), %rax
movq %rax, -0xa8(%rbp)
leaq 0x10(%rbp), %rax
movq %rax, -0xc0(%rbp)
movsd %xmm0, -0x8(%rbp)
leaq -0x20(%rbp), %rdi
xorps %xmm2, %xmm2
movaps %xmm2, %xmm0
movaps %xmm2, %xmm1
callq 0xea8e0
movq -0xb8(%rbp), %rdi
xorps %xmm2, %xmm2
movaps %xmm2, %xmm0
movaps %xmm2, %xmm1
callq 0xea8e0
leaq -0x38(%rbp), %rdi
xorps %xmm2, %xmm2
movaps %xmm2, %xmm0
movaps %xmm2, %xmm1
callq 0xea8e0
movq -0xc0(%rbp), %rsi
movq -0xa8(%rbp), %rdx
leaq -0x58(%rbp), %rdi
callq 0xeadf0
movq -0xb8(%rbp), %rdi
movq -0xb0(%rbp), %rsi
movq -0xa8(%rbp), %rdx
movq -0x58(%rbp), %rax
movq %rax, (%rdi)
movq -0x50(%rbp), %rax
movq %rax, 0x8(%rdi)
movq -0x48(%rbp), %rax
movq %rax, 0x10(%rdi)
leaq -0x88(%rbp), %rdi
callq 0xeadf0
leaq -0x70(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0xeaa90
movq -0x70(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x68(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x10(%rbp)
movsd -0x18(%rbp), %xmm0
movsd -0x18(%rbp), %xmm2
movsd -0x10(%rbp), %xmm1
mulsd -0x10(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
callq 0x53f0
movsd %xmm0, -0x40(%rbp)
movsd -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0xeb6b7
jp 0xeb6b7
jmp 0xeb717
movq -0xb8(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
movsd 0x8(%rax), %xmm0
mulsd -0x10(%rbp), %xmm0
divsd -0x40(%rbp), %xmm0
movsd 0x10(%rax), %xmm1
mulsd -0x18(%rbp), %xmm1
divsd -0x40(%rbp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, -0x30(%rbp)
movsd 0x8(%rax), %xmm0
mulsd -0x18(%rbp), %xmm0
divsd -0x40(%rbp), %xmm0
movsd 0x10(%rax), %xmm1
mulsd -0x10(%rbp), %xmm1
divsd -0x40(%rbp), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -0x28(%rbp)
jmp 0xeb735
movq -0xb8(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x38(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x30(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0xb8(%rbp), %rax
movsd -0x38(%rbp), %xmm0
movsd -0x40(%rbp), %xmm2
movsd -0x28(%rbp), %xmm1
mulsd -0x20(%rbp), %xmm1
movq %xmm1, %rcx
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
xorq %rdx, %rcx
movq %rcx, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movsd -0x30(%rbp), %xmm0
movsd %xmm0, 0x8(%rax)
movsd -0x38(%rbp), %xmm0
movsd -0x20(%rbp), %xmm2
movsd -0x28(%rbp), %xmm1
mulsd -0x40(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x10(%rax)
movsd (%rax), %xmm0
movsd %xmm0, -0xe8(%rbp)
movsd -0x8(%rbp), %xmm0
callq 0x5970
movq -0xb8(%rbp), %rax
movsd %xmm0, -0xf0(%rbp)
movsd 0x8(%rax), %xmm0
movsd %xmm0, -0xf8(%rbp)
movsd -0x8(%rbp), %xmm0
callq 0x5140
movsd -0xf8(%rbp), %xmm1
movsd -0xf0(%rbp), %xmm2
movq -0xb8(%rbp), %rax
movaps %xmm0, %xmm3
movsd -0xe8(%rbp), %xmm0
mulsd %xmm3, %xmm1
movq %xmm1, %rcx
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
xorq %rdx, %rcx
movq %rcx, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x38(%rbp)
movsd (%rax), %xmm0
movsd %xmm0, -0xd0(%rbp)
movsd -0x8(%rbp), %xmm0
callq 0x5140
movq -0xb8(%rbp), %rax
movsd %xmm0, -0xd8(%rbp)
movsd 0x8(%rax), %xmm0
movsd %xmm0, -0xe0(%rbp)
movsd -0x8(%rbp), %xmm0
callq 0x5970
movsd -0xe0(%rbp), %xmm1
movsd -0xd8(%rbp), %xmm2
movq -0xb8(%rbp), %rax
movaps %xmm0, %xmm3
movsd -0xd0(%rbp), %xmm0
mulsd %xmm3, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x30(%rbp)
movsd 0x10(%rax), %xmm0
movsd %xmm0, -0x28(%rbp)
movsd -0x38(%rbp), %xmm0
movsd -0x40(%rbp), %xmm2
movsd -0x28(%rbp), %xmm1
mulsd -0x20(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movsd -0x30(%rbp), %xmm0
movsd %xmm0, 0x8(%rax)
movsd -0x38(%rbp), %xmm0
movq %xmm0, %rcx
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
xorq %rdx, %rcx
movq %rcx, %xmm0
movsd -0x20(%rbp), %xmm2
movsd -0x28(%rbp), %xmm1
mulsd -0x40(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x10(%rax)
movsd -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0xeb911
jp 0xeb911
jmp 0xeb988
movq -0xb8(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
movsd 0x8(%rax), %xmm0
mulsd -0x10(%rbp), %xmm0
divsd -0x40(%rbp), %xmm0
movsd 0x10(%rax), %xmm1
mulsd -0x18(%rbp), %xmm1
divsd -0x40(%rbp), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -0x30(%rbp)
movsd 0x8(%rax), %xmm0
movq %xmm0, %rcx
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
xorq %rdx, %rcx
movq %rcx, %xmm0
mulsd -0x18(%rbp), %xmm0
divsd -0x40(%rbp), %xmm0
movsd 0x10(%rax), %xmm1
mulsd -0x10(%rbp), %xmm1
divsd -0x40(%rbp), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -0x28(%rbp)
jmp 0xeb9a6
movq -0xb8(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x38(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x30(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0xa8(%rbp), %rdx
leaq -0xa0(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0xeae50
movq -0xb8(%rbp), %rcx
movq -0xc8(%rbp), %rax
movq -0xa0(%rbp), %rdx
movq %rdx, (%rcx)
movq -0x98(%rbp), %rdx
movq %rdx, 0x8(%rcx)
movq -0x90(%rbp), %rdx
movq %rdx, 0x10(%rcx)
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
nopw %cs:(%rax,%rax)