// File: /workspace/github_cpp_makefile_star2_O2/marxn[P]pupp/3rdparty/gmp/mpn/mu_div_q.c
// Function: _gmpn_mu_div_q
mp_limb_t
mpn_mu_div_q (mp_ptr qp,
	      mp_srcptr np, mp_size_t nn,
	      mp_srcptr dp, mp_size_t dn,
	      mp_ptr scratch)
{
  mp_ptr tp, rp;
  mp_size_t qn;
  mp_limb_t cy, qh;
  TMP_DECL;

  TMP_MARK;

  qn = nn - dn;

  tp = TMP_BALLOC_LIMBS (qn + 1);

  if (qn >= dn)			/* nn >= 2*dn + 1 */
    {
       /* |_______________________|   dividend
			 |________|   divisor  */

      rp = TMP_BALLOC_LIMBS (nn + 1);
      MPN_COPY (rp + 1, np, nn);
      rp[0] = 0;

      qh = mpn_cmp (rp + 1 + nn - dn, dp, dn) >= 0;
      if (qh != 0)
	mpn_sub_n (rp + 1 + nn - dn, rp + 1 + nn - dn, dp, dn);

      cy = mpn_mu_divappr_q (tp, rp, nn + 1, dp, dn, scratch);

      if (UNLIKELY (cy != 0))
	{
	  /* Since the partial remainder fed to mpn_preinv_mu_divappr_q was
	     canonically reduced, replace the returned value of B^(qn-dn)+eps
	     by the largest possible value.  */
	  mp_size_t i;
	  for (i = 0; i < qn + 1; i++)
	    tp[i] = GMP_NUMB_MAX;
	}

      /* The max error of mpn_mu_divappr_q is +4.  If the low quotient limb is
	 smaller than the max error, we cannot trust the quotient.  */
      if (tp[0] > 4)
	{
	  MPN_COPY (qp, tp + 1, qn);
	}
      else
	{
	  mp_limb_t cy;
	  mp_ptr pp;

	  pp = rp;
	  mpn_mul (pp, tp + 1, qn, dp, dn);

	  cy = (qh != 0) ? mpn_add_n (pp + qn, pp + qn, dp, dn) : 0;

	  if (cy || mpn_cmp (pp, np, nn) > 0) /* At most is wrong by one, no cycle. */
	    qh -= mpn_sub_1 (qp, tp + 1, qn, 1);
	  else /* Same as above */
	    MPN_COPY (qp, tp + 1, qn);
	}
    }
  else
    {
       /* |_______________________|   dividend
		 |________________|   divisor  */

      /* FIXME: When nn = 2dn-1, qn becomes dn-1, and the numerator size passed
	 here becomes 2dn, i.e., more than nn.  This shouldn't hurt, since only
	 the most significant dn-1 limbs will actually be read, but it is not
	 pretty.  */

      qh = mpn_mu_divappr_q (tp, np + nn - (2 * qn + 2), 2 * qn + 2,
			     dp + dn - (qn + 1), qn + 1, scratch);

      /* The max error of mpn_mu_divappr_q is +4, but we get an additional
         error from the divisor truncation.  */
      if (tp[0] > 6)
	{
	  MPN_COPY (qp, tp + 1, qn);
	}
      else
	{
	  mp_limb_t cy;

	  /* FIXME: a shorter product should be enough; we may use already
	     allocated space... */
	  rp = TMP_BALLOC_LIMBS (nn);
	  mpn_mul (rp, dp, dn, tp + 1, qn);

	  cy = (qh != 0) ? mpn_add_n (rp + qn, rp + qn, dp, dn) : 0;

	  if (cy || mpn_cmp (rp, np, nn) > 0) /* At most is wrong by one, no cycle. */
	    qh -= mpn_sub_1 (qp, tp + 1, qn, 1);
	  else /* Same as above */
	    MPN_COPY (qp, tp + 1, qn);
	}
    }

  TMP_FREE;
  return qh;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %r9, %rbp
movq %r8, %r14
movq %rcx, 0x20(%rsp)
movq %rdx, %r13
movq %rsi, %r15
leaq 0x28(%rsp), %rax
andq $0x0, (%rax)
movq %rdi, %r12
movq %rdx, %rbx
subq %r8, %rbx
leaq 0x8(,%rbx,8), %rsi
movq %rax, %rdi
callq 0x29dc0
movq %rax, 0x8(%rsp)
movq %rax, %rdi
cmpq %r14, %rbx
movq %r12, 0x10(%rsp)
movq %r15, 0x38(%rsp)
jge 0x28cca
leaq 0x1(%rbx), %r8
leaq (%r15,%r13,8), %rax
leaq 0x2(,%rbx,2), %rdx
movq %rbx, %rsi
notq %rsi
movq 0x20(%rsp), %rcx
leaq (%rcx,%r14,8), %rcx
leaq (%rcx,%rsi,8), %rcx
shlq $0x4, %rsi
addq %rax, %rsi
movq %rdi, %r12
movq %rbp, %r9
callq 0x28628
movq %rax, %r15
cmpq $0x7, (%r12)
jb 0x28dc2
movq 0x8(%rsp), %rsi
addq $0x8, %rsi
movq 0x10(%rsp), %rdi
movq %rbx, %rdx
callq 0x290c6
jmp 0x28ebc
movq %rbp, 0x48(%rsp)
movq %rdi, 0x50(%rsp)
leaq 0x1(%r13), %rax
movq %rax, 0x40(%rsp)
leaq 0x8(,%r13,8), %rsi
leaq 0x28(%rsp), %rdi
callq 0x29dc0
movq 0x20(%rsp), %rbp
movq %r13, %r12
movq %rax, %r13
leaq 0x8(%rax), %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x290c6
andq $0x0, (%r13)
movq %r12, 0x18(%rsp)
leaq 0x8(,%r12,8), %r12
addq %r13, %r12
leaq (,%r14,8), %rax
subq %rax, %r12
movq %r12, %rdi
movq %rbp, %rsi
movq %r14, %rdx
callq 0x1ac5c
movq $0x0, (%rsp)
movl %eax, 0x34(%rsp)
testl %eax, %eax
setns %r15b
js 0x28d5c
movq %r12, %rdi
movq %r12, %rsi
movq %rbp, %rdx
movq %r14, %rcx
callq 0x17ed0
movq (%rsp), %rax
movb %r15b, %al
movq %rax, (%rsp)
movq 0x50(%rsp), %r12
movq %r12, %rdi
movq %r13, %rsi
movq 0x40(%rsp), %rdx
movq %rbp, %r15
movq %rbp, %rcx
movq %r14, %r8
movq 0x48(%rsp), %r9
callq 0x28628
movq %r12, %rcx
testq %rax, %rax
movq 0x10(%rsp), %rdi
movq 0x8(%rsp), %r12
jne 0x28ef6
addq $0x8, %r12
cmpq $0x5, (%rcx)
jb 0x28e53
movq %r12, %rsi
movq %rbx, %rdx
callq 0x290c6
movq (%rsp), %r15
jmp 0x28ebc
movq %r13, 0x18(%rsp)
leaq (,%r13,8), %rsi
leaq 0x28(%rsp), %rdi
callq 0x29dc0
movq 0x20(%rsp), %r13
movq %rax, %rbp
movq 0x8(%rsp), %rcx
addq $0x8, %rcx
movq %rax, %rdi
movq %r13, %rsi
movq %r14, %rdx
movq %rcx, 0x8(%rsp)
movq %rbx, %r8
callq 0x18a58
movq %r15, (%rsp)
testq %r15, %r15
movq 0x10(%rsp), %r15
je 0x28e2c
leaq (,%rbx,8), %rdi
addq %rbp, %rdi
movq %rdi, %rsi
movq %r13, %rdx
movq %r14, %rcx
callq 0x17cf0
testq %rax, %rax
jne 0x28e46
movq %rbp, %rdi
movq 0x38(%rsp), %rsi
movq 0x18(%rsp), %rdx
callq 0x1ac5c
testl %eax, %eax
jle 0x28ed8
pushq $0x1
popq %rcx
movq %r15, %rdi
movq 0x8(%rsp), %rsi
jmp 0x28ead
movq %r13, %rdi
movq %r12, %rsi
movq %rbx, %rdx
movq %r15, %rcx
movq %r14, %r8
callq 0x18a58
cmpl $0x0, 0x34(%rsp)
js 0x28e8c
leaq (,%rbx,8), %rdi
addq %r13, %rdi
movq %rdi, %rsi
movq %r15, %rdx
movq %r14, %rcx
callq 0x17cf0
testq %rax, %rax
jne 0x28ea2
movq %r13, %rdi
movq 0x38(%rsp), %rsi
movq 0x18(%rsp), %rdx
callq 0x1ac5c
testl %eax, %eax
jle 0x28ee5
pushq $0x1
popq %rcx
movq 0x10(%rsp), %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0x17e44
movq (%rsp), %r15
subq %rax, %r15
movq 0x28(%rsp), %rdi
testq %rdi, %rdi
jne 0x28eef
movq %r15, %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r15, %rdi
movq 0x8(%rsp), %rsi
jmp 0x28db1
movq 0x10(%rsp), %rdi
jmp 0x28dae
callq 0x29df3
jmp 0x28ec6
xorl %eax, %eax
cmpq %rbx, %rax
jg 0x28da0
orq $-0x1, (%rcx,%rax,8)
incq %rax
jmp 0x28ef8