// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %r9, %rbx
movq %r8, %r14
movq %rcx, %r15
movl %esi, %r12d
movq %rdi, %r13
ucomisd %xmm0, %xmm2
jne 0xcca8
jp 0xcca8
ucomisd %xmm1, %xmm3
jne 0xcca8
jp 0xcca8
leaq 0x2160c(%rip), %rdi     # 0x2e2af
jmp 0xcd2b
movaps 0x21371(%rip), %xmm6    # 0x2e020
andps %xmm4, %xmm6
movaps %xmm6, -0x50(%rbp)
movaps %xmm4, -0x60(%rbp)
movapd %xmm0, %xmm4
addsd %xmm2, %xmm4
movsd %xmm0, -0x70(%rbp)
movsd 0x21339(%rip), %xmm0    # 0x2e008
mulsd %xmm0, %xmm4
movsd %xmm1, -0x78(%rbp)
addsd %xmm3, %xmm1
mulsd %xmm0, %xmm1
movsd %xmm4, -0x88(%rbp)
movapd %xmm4, %xmm0
subsd %xmm2, %xmm0
movsd %xmm1, -0x90(%rbp)
movsd %xmm3, -0x80(%rbp)
subsd %xmm3, %xmm1
movsd %xmm2, -0x68(%rbp)
movsd %xmm5, -0x38(%rbp)
callq 0xb2c0
movapd %xmm0, %xmm1
movapd -0x50(%rbp), %xmm3
subsd %xmm3, %xmm1
ucomisd -0x38(%rbp), %xmm1
jbe 0xcd74
leaq 0x21617(%rip), %rdi     # 0x2e342
callq 0xb220
movq %r13, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0xb8e0
movq 0x3021c(%rip), %rbx     # 0x3cf60
leaq 0xc6d0(%rbx), %rdi
leaq 0x21584(%rip), %rsi     # 0x2e2d6
pushq $0x50
popq %rdx
callq 0xb940
andw $0x0, 0xc71f(%rbx)
movl $0x1, 0xd670(%rbx)
pushq $0x5
popq %rax
jmp 0xce88
movapd %xmm3, %xmm2
movapd %xmm0, %xmm1
divsd %xmm3, %xmm1
movsd 0x21288(%rip), %xmm3    # 0x2e010
cmpltsd %xmm1, %xmm3
movapd %xmm3, %xmm1
andnpd %xmm0, %xmm3
movapd %xmm3, %xmm4
xorpd %xmm0, %xmm0
movapd -0x60(%rbp), %xmm3
ucomisd %xmm3, %xmm0
fldt 0x21284(%rip)           # 0x2e030
fldt 0x2128e(%rip)           # 0x2e040
fld %st(0)
fcmovnbe %st(2), %st
cmpl $0x1e, %r12d
fxch %st(1)
fcmove %st(1), %st
fstp %st(1)
andpd %xmm2, %xmm1
ucomisd %xmm0, %xmm3
fld %st(0)
fcmovnbe %st(2), %st
fstp %st(2)
xorl %r13d, %r13d
cmpl $0x14, %r12d
fcmove %st(1), %st
fstp %st(1)
fstpt -0x38(%rbp)
orpd %xmm1, %xmm4
movapd %xmm4, -0x60(%rbp)
setne %r13b
movsd -0x80(%rbp), %xmm0
subsd -0x78(%rbp), %xmm0
movsd -0x68(%rbp), %xmm1
subsd -0x70(%rbp), %xmm1
callq 0xb110
movsd %xmm0, -0xa0(%rbp)
fldt -0x38(%rbp)
faddl -0xa0(%rbp)
fstpl -0x98(%rbp)
movsd -0x98(%rbp), %xmm0
movsd %xmm0, -0x38(%rbp)
movapd -0x60(%rbp), %xmm0
divsd -0x50(%rbp), %xmm0
callq 0xc3b0
callq 0xc6c0
mulsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x50(%rbp)
movsd -0x38(%rbp), %xmm0
callq 0xc6c0
mulsd -0x50(%rbp), %xmm0
addsd -0x88(%rbp), %xmm0
movsd %xmm0, (%r15)
movsd -0x38(%rbp), %xmm0
callq 0xb200
mulsd -0x50(%rbp), %xmm0
addsd -0x90(%rbp), %xmm0
movsd %xmm0, (%r14)
leal -0x1(,%r13,2), %eax
movl %eax, (%rbx)
xorl %eax, %eax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop