// File: sundale[P]gcode/rs274ngc/interp_arc.cc
// Function: Interp::arc_data_r(int, int, double, double, double, double, double, double*, double*, int*, double)
int Interp::arc_data_r(int move, //!< either G_2 (cw arc) or G_3 (ccw arc)
                       int plane,
                      double current_x, //!< first coordinate of current point
                      double current_y, //!< second coordinate of current point
                      double end_x,     //!< first coordinate of arc end point
                      double end_y,     //!< second coordinate of arc end point
                      double radius,    //!< radius of arc
                      double *center_x, //!< pointer to first coordinate of center of arc
                      double *center_y, //!< pointer to second coordinate of center of arc
                      int *turn,        //!< pointer to number of full or partial circles CCW
                      double tolerance) //!< tolerance of differing radii
{
  double abs_radius;            /* absolute value of given radius */
  double half_length;           /* distance from M to end point   */
  double mid_x;                 /* first coordinate of M          */
  double mid_y;                 /* second coordinate of M         */
  double offset;                /* distance from M to center      */
  double theta;                 /* angle of line from M to center */
  double turn2;                 /* absolute value of half of turn */

  CHKS(((end_x == current_x) && (end_y == current_y)),
      NCE_CURRENT_POINT_SAME_AS_END_POINT_OF_ARC);
  abs_radius = fabs(radius);
  mid_x = (end_x + current_x) / 2.0;
  mid_y = (end_y + current_y) / 2.0;
  half_length = hypot((mid_x - end_x), (mid_y - end_y));
  CHKS(((half_length - abs_radius) > tolerance),
      NCE_ARC_RADIUS_TOO_SMALL_TO_REACH_END_POINT);
  if ((half_length / abs_radius) > (1 - TINY))
    half_length = abs_radius;   /* allow a small error for semicircle */
  /* check needed before calling asin   */
  if (((move == G_2) && (radius > 0)) || ((move == G_3) && (radius < 0)))
    theta = atan2((end_y - current_y), (end_x - current_x)) - M_PI_2l;
  else
    theta = atan2((end_y - current_y), (end_x - current_x)) + M_PI_2l;

  turn2 = asin(half_length / abs_radius);
  offset = abs_radius * cos(turn2);
  *center_x = mid_x + (offset * cos(theta));
  *center_y = mid_y + (offset * sin(theta));
  *turn = (move == G_2) ? -1 : 1;

  return INTERP_OK;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movsd %xmm0, -0x20(%rbp)
movsd %xmm1, -0x28(%rbp)
movsd %xmm2, -0x30(%rbp)
movsd %xmm3, -0x38(%rbp)
movsd %xmm4, -0x40(%rbp)
movq %rcx, -0x48(%rbp)
movq %r8, -0x50(%rbp)
movq %r9, -0x58(%rbp)
movsd %xmm5, -0x60(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xc0(%rbp)
movsd -0x30(%rbp), %xmm0
ucomisd -0x20(%rbp), %xmm0
jne 0x12e4e
jp 0x12e4e
movsd -0x38(%rbp), %xmm0
ucomisd -0x28(%rbp), %xmm0
jne 0x12e4e
jp 0x12e4e
jmp 0x12d78
leaq 0x64530(%rip), %rdi     # 0x772af
callq 0x10380
movq -0xc0(%rbp), %rdi
movq %rax, %rsi
movb $0x0, %al
callq 0x10df0
movq 0x741c4(%rip), %rax     # 0x86f60
movl $0x0, 0xd670(%rax)
movq 0x741b3(%rip), %rax     # 0x86f60
movslq 0xd670(%rax), %rax
movq 0x741a5(%rip), %rdi     # 0x86f60
addq $0xc6d0, %rdi           # imm = 0xC6D0
imulq $0x50, %rax, %rax
addq %rax, %rdi
leaq 0x64506(%rip), %rsi     # 0x772d6
movl $0x50, %edx
callq 0x10840
movq 0x7417f(%rip), %rax     # 0x86f60
movslq 0xd670(%rax), %rcx
movq 0x74171(%rip), %rax     # 0x86f60
addq $0xc6d0, %rax           # imm = 0xC6D0
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movb $0x0, 0x4f(%rax)
movq 0x74159(%rip), %rax     # 0x86f60
movl 0xd670(%rax), %ecx
addl $0x1, %ecx
movq 0x74149(%rip), %rax     # 0x86f60
movl %ecx, 0xd670(%rax)
movq 0x7413c(%rip), %rax     # 0x86f60
movslq 0xd670(%rax), %rcx
movq 0x7412e(%rip), %rax     # 0x86f60
addq $0xc6d0, %rax           # imm = 0xC6D0
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movb $0x0, (%rax)
movl $0x5, -0x4(%rbp)
jmp 0x1318c
jmp 0x12e50
movsd -0x40(%rbp), %xmm0
movaps 0x641c4(%rip), %xmm1    # 0x77020
pand %xmm1, %xmm0
movsd %xmm0, -0x68(%rbp)
movsd -0x30(%rbp), %xmm0
addsd -0x20(%rbp), %xmm0
movsd 0x64191(%rip), %xmm1    # 0x77008
divsd %xmm1, %xmm0
movsd %xmm0, -0x78(%rbp)
movsd -0x38(%rbp), %xmm0
addsd -0x28(%rbp), %xmm0
movsd 0x64176(%rip), %xmm1    # 0x77008
divsd %xmm1, %xmm0
movsd %xmm0, -0x80(%rbp)
movsd -0x78(%rbp), %xmm0
subsd -0x30(%rbp), %xmm0
movsd -0x80(%rbp), %xmm1
subsd -0x38(%rbp), %xmm1
callq 0x10460
movsd %xmm0, -0x70(%rbp)
movsd -0x70(%rbp), %xmm0
subsd -0x68(%rbp), %xmm0
ucomisd -0x60(%rbp), %xmm0
jbe 0x12fa6
jmp 0x12ed0
leaq 0x6446b(%rip), %rdi     # 0x77342
callq 0x10380
movq -0xc0(%rbp), %rdi
movq %rax, %rsi
movb $0x0, %al
callq 0x10df0
movq 0x7406c(%rip), %rax     # 0x86f60
movl $0x0, 0xd670(%rax)
movq 0x7405b(%rip), %rax     # 0x86f60
movslq 0xd670(%rax), %rax
movq 0x7404d(%rip), %rdi     # 0x86f60
addq $0xc6d0, %rdi           # imm = 0xC6D0
imulq $0x50, %rax, %rax
addq %rax, %rdi
leaq 0x643ae(%rip), %rsi     # 0x772d6
movl $0x50, %edx
callq 0x10840
movq 0x74027(%rip), %rax     # 0x86f60
movslq 0xd670(%rax), %rcx
movq 0x74019(%rip), %rax     # 0x86f60
addq $0xc6d0, %rax           # imm = 0xC6D0
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movb $0x0, 0x4f(%rax)
movq 0x74001(%rip), %rax     # 0x86f60
movl 0xd670(%rax), %ecx
addl $0x1, %ecx
movq 0x73ff1(%rip), %rax     # 0x86f60
movl %ecx, 0xd670(%rax)
movq 0x73fe4(%rip), %rax     # 0x86f60
movslq 0xd670(%rax), %rcx
movq 0x73fd6(%rip), %rax     # 0x86f60
addq $0xc6d0, %rax           # imm = 0xC6D0
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movb $0x0, (%rax)
movl $0x5, -0x4(%rbp)
jmp 0x1318c
jmp 0x12fa8
movsd -0x70(%rbp), %xmm0
divsd -0x68(%rbp), %xmm0
movsd 0x64056(%rip), %xmm1    # 0x77010
ucomisd %xmm1, %xmm0
jbe 0x12fca
movsd -0x68(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
cmpl $0x14, -0x14(%rbp)
jne 0x12fde
movsd -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
ja 0x12fee
cmpl $0x1e, -0x14(%rbp)
jne 0x1303d
xorps %xmm0, %xmm0
ucomisd -0x40(%rbp), %xmm0
jbe 0x1303d
movsd -0x38(%rbp), %xmm0
movsd -0x28(%rbp), %xmm1
subsd %xmm1, %xmm0
movsd -0x30(%rbp), %xmm1
movsd -0x20(%rbp), %xmm2
subsd %xmm2, %xmm1
callq 0x101d0
movsd %xmm0, -0xb0(%rbp)
fldl -0xb0(%rbp)
fldt 0x6401d(%rip)           # 0x77040
faddp %st, %st(1)
fstpl -0xb8(%rbp)
movsd -0xb8(%rbp), %xmm0
movsd %xmm0, -0x90(%rbp)
jmp 0x1308a
movsd -0x38(%rbp), %xmm0
movsd -0x28(%rbp), %xmm1
subsd %xmm1, %xmm0
movsd -0x30(%rbp), %xmm1
movsd -0x20(%rbp), %xmm2
subsd %xmm2, %xmm1
callq 0x101d0
movsd %xmm0, -0xa0(%rbp)
fldl -0xa0(%rbp)
fldt 0x63fbe(%rip)           # 0x77030
faddp %st, %st(1)
fstpl -0xa8(%rbp)
movsd -0xa8(%rbp), %xmm0
movsd %xmm0, -0x90(%rbp)
movsd -0x70(%rbp), %xmm0
divsd -0x68(%rbp), %xmm0
callq 0x11d80
movsd %xmm0, -0x98(%rbp)
movsd -0x68(%rbp), %xmm0
movsd %xmm0, -0xe8(%rbp)
movsd -0x98(%rbp), %xmm0
callq 0x12160
movaps %xmm0, %xmm1
movsd -0xe8(%rbp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, -0x88(%rbp)
movsd -0x78(%rbp), %xmm0
movsd %xmm0, -0xe0(%rbp)
movsd -0x88(%rbp), %xmm0
movsd %xmm0, -0xd8(%rbp)
movsd -0x90(%rbp), %xmm0
callq 0x12160
movsd -0xe0(%rbp), %xmm1
movaps %xmm0, %xmm2
movsd -0xd8(%rbp), %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movq -0x48(%rbp), %rax
movsd %xmm0, (%rax)
movsd -0x80(%rbp), %xmm0
movsd %xmm0, -0xd0(%rbp)
movsd -0x88(%rbp), %xmm0
movsd %xmm0, -0xc8(%rbp)
movsd -0x90(%rbp), %xmm0
callq 0x10330
movsd -0xd0(%rbp), %xmm1
movaps %xmm0, %xmm2
movsd -0xc8(%rbp), %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movq -0x50(%rbp), %rax
movsd %xmm0, (%rax)
movl -0x14(%rbp), %edx
movl $0x1, %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpl $0x14, %edx
cmovel %eax, %ecx
movq -0x58(%rbp), %rax
movl %ecx, (%rax)
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xf0, %rsp
popq %rbp
retq
nopl (%rax,%rax)