// File: 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
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq $0x0, -0x60(%rbp)
movq -0x18(%rbp), %rax
subq -0x28(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rsi
addq $0x1, %rsi
shlq $0x3, %rsi
leaq -0x60(%rbp), %rdi
callq 0x56430
movq %rax, -0x38(%rbp)
movq -0x48(%rbp), %rax
cmpq -0x28(%rbp), %rax
jl 0x5510a
movq -0x18(%rbp), %rsi
addq $0x1, %rsi
shlq $0x3, %rsi
leaq -0x60(%rbp), %rdi
callq 0x56430
movq %rax, -0x40(%rbp)
jmp 0x54ea9
jmp 0x54eab
jmp 0x54ead
jmp 0x54eaf
jmp 0x54eb1
jmp 0x54eb3
jmp 0x54eb5
movq -0x40(%rbp), %rdi
addq $0x8, %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x554c6
jmp 0x54ecc
movq -0x40(%rbp), %rax
movq $0x0, (%rax)
movq -0x40(%rbp), %rdi
addq $0x8, %rdi
movq -0x18(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
xorl %eax, %eax
subq -0x28(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x3b060
cmpl $0x0, %eax
setge %al
andb $0x1, %al
movzbl %al, %eax
cltq
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x58(%rbp)
je 0x54f69
movq -0x40(%rbp), %rdi
addq $0x8, %rdi
movq -0x18(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
xorl %eax, %eax
subq -0x28(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
movq -0x40(%rbp), %rsi
addq $0x8, %rsi
movq -0x18(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
xorl %eax, %eax
subq -0x28(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
callq 0x36fe0
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x18(%rbp), %rdx
addq $0x1, %rdx
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x30(%rbp), %r9
callq 0x54300
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
setne %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movzbl %al, %eax
cltq
cmpq $0x0, %rax
je 0x54fe7
movq $0x0, -0x68(%rbp)
movq -0x68(%rbp), %rax
movq -0x48(%rbp), %rcx
addq $0x1, %rcx
cmpq %rcx, %rax
jge 0x54fe5
movq -0x38(%rbp), %rax
movq -0x68(%rbp), %rcx
movq $-0x1, (%rax,%rcx,8)
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x68(%rbp)
jmp 0x54fb6
jmp 0x54fe7
movq -0x38(%rbp), %rax
cmpq $0x4, (%rax)
jbe 0x5501d
jmp 0x54ff3
jmp 0x54ff5
jmp 0x54ff7
jmp 0x54ff9
jmp 0x54ffb
jmp 0x54ffd
jmp 0x54fff
jmp 0x55001
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rsi
addq $0x8, %rsi
movq -0x48(%rbp), %rdx
callq 0x554c6
jmp 0x55018
jmp 0x55105
movq -0x40(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdi
movq -0x38(%rbp), %rsi
addq $0x8, %rsi
movq -0x48(%rbp), %rdx
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
callq 0x37f00
cmpq $0x0, -0x58(%rbp)
je 0x5507d
movq -0x78(%rbp), %rdi
movq -0x48(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
movq -0x78(%rbp), %rsi
movq -0x48(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
callq 0x36c80
movq %rax, -0x88(%rbp)
jmp 0x55088
xorl %eax, %eax
movq %rax, -0x88(%rbp)
jmp 0x55088
movq -0x88(%rbp), %rax
movq %rax, -0x70(%rbp)
cmpq $0x0, -0x70(%rbp)
jne 0x550b0
movq -0x78(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x3b060
cmpl $0x0, %eax
jle 0x550da
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rsi
addq $0x8, %rsi
movq -0x48(%rbp), %rdx
movl $0x1, %ecx
callq 0x36e60
movq %rax, %rcx
movq -0x58(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x58(%rbp)
jmp 0x55103
jmp 0x550dc
jmp 0x550de
jmp 0x550e0
jmp 0x550e2
jmp 0x550e4
jmp 0x550e6
jmp 0x550e8
jmp 0x550ea
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rsi
addq $0x8, %rsi
movq -0x48(%rbp), %rdx
callq 0x554c6
jmp 0x55101
jmp 0x55103
jmp 0x55105
jmp 0x552a4
movq -0x38(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
movq -0x48(%rbp), %rcx
shlq %rcx
addq $0x2, %rcx
xorl %eax, %eax
subq %rcx, %rax
shlq $0x3, %rax
addq %rax, %rsi
movq -0x48(%rbp), %rdx
shlq %rdx
addq $0x2, %rdx
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rcx
movq -0x48(%rbp), %r8
addq $0x1, %r8
xorl %eax, %eax
subq %r8, %rax
shlq $0x3, %rax
addq %rax, %rcx
movq -0x48(%rbp), %r8
addq $0x1, %r8
movq -0x30(%rbp), %r9
callq 0x54300
movq %rax, -0x58(%rbp)
movq -0x38(%rbp), %rax
cmpq $0x6, (%rax)
jbe 0x551ad
jmp 0x55183
jmp 0x55185
jmp 0x55187
jmp 0x55189
jmp 0x5518b
jmp 0x5518d
jmp 0x5518f
jmp 0x55191
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rsi
addq $0x8, %rsi
movq -0x48(%rbp), %rdx
callq 0x554c6
jmp 0x551a8
jmp 0x552a2
movq -0x18(%rbp), %rsi
shlq $0x3, %rsi
leaq -0x60(%rbp), %rdi
callq 0x56430
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movq -0x38(%rbp), %rcx
addq $0x8, %rcx
movq -0x48(%rbp), %r8
callq 0x37f00
cmpq $0x0, -0x58(%rbp)
je 0x5521a
movq -0x40(%rbp), %rdi
movq -0x48(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
movq -0x40(%rbp), %rsi
movq -0x48(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
callq 0x36c80
movq %rax, -0x90(%rbp)
jmp 0x55225
xorl %eax, %eax
movq %rax, -0x90(%rbp)
jmp 0x55225
movq -0x90(%rbp), %rax
movq %rax, -0x80(%rbp)
cmpq $0x0, -0x80(%rbp)
jne 0x5524d
movq -0x40(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x3b060
cmpl $0x0, %eax
jle 0x55277
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rsi
addq $0x8, %rsi
movq -0x48(%rbp), %rdx
movl $0x1, %ecx
callq 0x36e60
movq %rax, %rcx
movq -0x58(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x58(%rbp)
jmp 0x552a0
jmp 0x55279
jmp 0x5527b
jmp 0x5527d
jmp 0x5527f
jmp 0x55281
jmp 0x55283
jmp 0x55285
jmp 0x55287
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rsi
addq $0x8, %rsi
movq -0x48(%rbp), %rdx
callq 0x554c6
jmp 0x5529e
jmp 0x552a0
jmp 0x552a2
jmp 0x552a4
jmp 0x552a6
cmpq $0x0, -0x60(%rbp)
setne %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movzbl %al, %eax
cltq
cmpq $0x0, %rax
je 0x552cf
movq -0x60(%rbp), %rdi
callq 0x564a0
jmp 0x552d1
movq -0x58(%rbp), %rax
addq $0x90, %rsp
popq %rbp
retq
nop