// File: /workspace/github_cpp_makefile_star2_O1/marxn[P]pupp/3rdparty/gmp/mpn/mu_divappr_q.c
// Function: _gmpn_preinv_mu_divappr_q
mp_limb_t
mpn_preinv_mu_divappr_q (mp_ptr qp,
			 mp_srcptr np,
			 mp_size_t nn,
			 mp_srcptr dp,
			 mp_size_t dn,
			 mp_srcptr ip,
			 mp_size_t in,
			 mp_ptr scratch)
{
  mp_size_t qn;
  mp_limb_t cy, cx, qh;
  mp_limb_t r;
  mp_size_t tn, wn;

#define rp           scratch
#define tp           (scratch + dn)
#define scratch_out  (scratch + dn + tn)

  qn = nn - dn;

  np += qn;
  qp += qn;

  qh = mpn_cmp (np, dp, dn) >= 0;
  if (qh != 0)
    mpn_sub_n (rp, np, dp, dn);
  else
    MPN_COPY (rp, np, dn);

  if (qn == 0)
    return qh;			/* Degenerate use.  Should we allow this? */

  while (qn > 0)
    {
      if (qn < in)
	{
	  ip += in - qn;
	  in = qn;
	}
      np -= in;
      qp -= in;

      /* Compute the next block of quotient limbs by multiplying the inverse I
	 by the upper part of the partial remainder R.  */
      mpn_mul_n (tp, rp + dn - in, ip, in);		/* mulhi  */
      cy = mpn_add_n (qp, tp + in, rp + dn - in, in);	/* I's msb implicit */
      ASSERT_ALWAYS (cy == 0);

      qn -= in;
      if (qn == 0)
	break;

      /* Compute the product of the quotient block and the divisor D, to be
	 subtracted from the partial remainder combined with new limbs from the
	 dividend N.  We only really need the low dn limbs.  */

      if (BELOW_THRESHOLD (in, MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD))
	mpn_mul (tp, dp, dn, qp, in);		/* dn+in limbs, high 'in' cancels */
      else
	{
	  tn = mpn_mulmod_bnm1_next_size (dn + 1);
	  mpn_mulmod_bnm1 (tp, tn, dp, dn, qp, in, scratch_out);
	  wn = dn + in - tn;			/* number of wrapped limbs */
	  if (wn > 0)
	    {
	      cy = mpn_sub_n (tp, tp, rp + dn - wn, wn);
	      cy = mpn_sub_1 (tp + wn, tp + wn, tn - wn, cy);
	      cx = mpn_cmp (rp + dn - in, tp + dn, tn - dn) < 0;
	      ASSERT_ALWAYS (cx >= cy);
	      mpn_incr_u (tp, cx - cy);
	    }
	}

      r = rp[dn - in] - tp[dn];

      /* Subtract the product from the partial remainder combined with new
	 limbs from the dividend N, generating a new partial remainder R.  */
      if (dn != in)
	{
	  cy = mpn_sub_n (tp, np, tp, in);	/* get next 'in' limbs from N */
	  cy = mpn_sub_nc (tp + in, rp, tp + in, dn - in, cy);
	  MPN_COPY (rp, tp, dn);		/* FIXME: try to avoid this */
	}
      else
	{
	  cy = mpn_sub_n (rp, np, tp, in);	/* get next 'in' limbs from N */
	}

      STAT (int i; int err = 0;
	    static int errarr[5]; static int err_rec; static int tot);

      /* Check the remainder R and adjust the quotient as needed.  */
      r -= cy;
      while (r != 0)
	{
	  /* We loop 0 times with about 69% probability, 1 time with about 31%
	     probability, 2 times with about 0.6% probability, if inverse is
	     computed as recommended.  */
	  mpn_incr_u (qp, 1);
	  cy = mpn_sub_n (rp, rp, dp, dn);
	  r -= cy;
	  STAT (err++);
	}
      if (mpn_cmp (rp, dp, dn) >= 0)
	{
	  /* This is executed with about 76% probability.  */
	  mpn_incr_u (qp, 1);
	  cy = mpn_sub_n (rp, rp, dp, dn);
	  STAT (err++);
	}

      STAT (
	    tot++;
	    errarr[err]++;
	    if (err > err_rec)
	      err_rec = err;
	    if (tot % 0x10000 == 0)
	      {
		for (i = 0; i <= err_rec; i++)
		  printf ("  %d(%.1f%%)", errarr[i], 100.0*errarr[i]/tot);
		printf ("\n");
	      }
	    );
    }

  /* FIXME: We should perhaps be somewhat more elegant in our rounding of the
     quotient.  For now, just make sure the returned quotient is >= the real
     quotient; add 3 with saturating arithmetic.  */
  qn = nn - dn;
  cy += mpn_add_1 (qp, qp, qn, 3);
  if (cy != 0)
    {
      if (qh != 0)
	{
	  /* Return a quotient of just 1-bits, with qh set.  */
	  mp_size_t i;
	  for (i = 0; i < qn; i++)
	    qp[i] = GMP_NUMB_MAX;
	}
      else
	{
	  /* Propagate carry into qh.  */
	  qh = 1;
	}
    }

  return qh;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %r9, %r12
movq %rcx, %r13
movq %rdx, %rbx
movq 0xc8(%rsp), %rbp
movq %rdx, %r14
subq %r8, %r14
leaq (%rsi,%r14,8), %r9
leaq (%rdi,%r14,8), %r15
leaq (%rsi,%rdx,8), %rax
addq $-0x8, %rax
movq %r8, 0x10(%rsp)
movq %r8, %rcx
testq %rcx, %rcx
jle 0x2e9cc
movq -0x8(%r13,%rcx,8), %rdx
decq %rcx
leaq -0x8(%rax), %rsi
cmpq %rdx, (%rax)
movq %rsi, %rax
je 0x2e9ae
seta %al
jmp 0x2e9ce
movb $0x1, %al
movzbl %al, %eax
movq %rax, 0x30(%rsp)
testb %al, %al
movq %r9, 0x50(%rsp)
movq %rbp, %rdi
movq %r9, %rsi
je 0x2e9f4
movq %r13, %rdx
movq 0x10(%rsp), %rcx
callq 0x1c1c0
jmp 0x2e9fe
movq 0x10(%rsp), %rdx
callq 0x2f4c6
testq %r14, %r14
je 0x2ed42
movq %r15, 0x20(%rsp)
movq %rbx, 0x58(%rsp)
movq %r14, 0x38(%rsp)
jle 0x2ed4c
movq %r12, 0x48(%rsp)
movq 0x10(%rsp), %rax
leaq (,%rax,8), %rdi
addq %rbp, %rdi
leaq 0x1(%rax), %rcx
movq %rcx, 0x68(%rsp)
leaq -0x8(%rbp), %rcx
movq %rcx, 0x60(%rsp)
negq %rax
movq %rax, 0x40(%rsp)
movq %r14, %r15
movq 0xc0(%rsp), %r14
movq %rdi, 0x18(%rsp)
movq %r14, %rax
movq %r15, %rcx
subq %r14, %rcx
cmovlq %r15, %r14
negq %rcx
cmpq %r15, %rax
movl $0x0, %eax
cmovleq %rax, %rcx
movq 0x48(%rsp), %rdx
leaq (%rdx,%rcx,8), %rdx
leaq (,%r14,8), %rax
movq %r14, %rbp
movq 0x20(%rsp), %r14
subq %rax, %r14
movq %rdi, %rbx
movq %rax, 0x28(%rsp)
subq %rax, %rbx
movq %rbx, %rsi
movq %rdx, 0x48(%rsp)
movq %rbp, %rcx
movq %rdi, %r12
callq 0x1d864
leaq (%r12,%rbp,8), %rsi
movq %r14, 0x20(%rsp)
movq %r14, %rdi
movq %rbp, %r14
movq %rsi, 0x70(%rsp)
movq %rbx, %rdx
movq %rbp, %rcx
callq 0x1bfa0
testq %rax, %rax
jne 0x2edf3
subq %r14, %r15
je 0x2ed4e
movq %r15, 0x80(%rsp)
cmpq $0x20, %r14
movq 0x10(%rsp), %rbx
jle 0x2ebaf
movq 0x68(%rsp), %rdi
callq 0x2aee3
movq %rax, %r12
movq 0x18(%rsp), %rbp
leaq (,%rax,8), %rax
addq %rbp, %rax
movq %rax, (%rsp)
movq %rbp, %rdi
movq %r12, %rsi
movq %r13, %rdx
movq %rbx, %rcx
movq 0x20(%rsp), %r15
movq %r15, %r8
movq %r14, %r9
callq 0x2a886
movq %rbp, %r8
movq %rbx, %rax
addq %r14, %rbx
subq %r12, %rbx
testq %rbx, %rbx
movq 0xc8(%rsp), %rbp
jle 0x2ec37
leaq (,%rbx,8), %rax
movq %r8, %rdx
subq %rax, %rdx
movq %r8, %rdi
movq %r8, %rsi
movq %rbx, %rcx
callq 0x1c1c0
movq 0x18(%rsp), %r8
subq %rax, (%r8,%rbx,8)
jae 0x2ebdd
leaq (%r8,%rbx,8), %rcx
movq %r12, %rdx
subq %rbx, %rdx
cmpq $0x2, %rdx
movl $0x1, %eax
cmovlq %rax, %rdx
movl $0x1, %esi
movq 0x40(%rsp), %rdi
cmpq %rsi, %rdx
je 0x2ebe4
subq $0x1, (%rcx,%rsi,8)
leaq 0x1(%rsi), %rsi
jb 0x2eb9b
xorl %eax, %eax
jmp 0x2ebe4
movq 0x18(%rsp), %r12
movq %r12, %rdi
movq %r13, %rsi
movq %rbx, %rdx
movq 0x20(%rsp), %r15
movq %r15, %rcx
movq %r14, %r8
callq 0x1cd58
movq %r12, %r8
movq %rbx, %rax
movq 0xc8(%rsp), %rbp
jmp 0x2ec37
xorl %eax, %eax
movq 0x40(%rsp), %rdi
movq 0x60(%rsp), %rcx
subq 0x28(%rsp), %rcx
leaq (%rdi,%r12), %rdx
testq %rdx, %rdx
jle 0x2ec12
movq -0x8(%r8,%r12,8), %rdx
leaq -0x1(%r12), %rsi
cmpq %rdx, (%rcx,%r12,8)
movq %rsi, %r12
je 0x2ebee
setbe %cl
movzbl %cl, %ecx
jmp 0x2ec14
xorl %ecx, %ecx
cmpl %eax, %ecx
jb 0x2edf8
subq %rax, %rcx
movq %r8, %rax
addq %rcx, (%rax)
jae 0x2ec32
addq $0x1, 0x8(%rax)
leaq 0x8(%rax), %rax
jb 0x2ec27
movq 0x10(%rsp), %rax
movq 0x50(%rsp), %rsi
subq 0x28(%rsp), %rsi
movq %rax, %rbx
movq (%r8,%rax,8), %rax
movq %rax, 0x28(%rsp)
subq %r14, %rbx
movq %r14, %rcx
movq (%rbp,%rbx,8), %r14
movq %rcx, 0x78(%rsp)
movq %rsi, 0x50(%rsp)
jne 0x2ec79
movq %rbp, %rdi
movq %r8, %rdx
callq 0x1c1c0
movq %rax, %r12
movq 0x10(%rsp), %rbx
jmp 0x2ecb2
movq %r8, %rdi
movq %r8, %rdx
callq 0x1c1c0
movq 0x70(%rsp), %rdi
movq %rbp, %rsi
movq %rdi, %rdx
movq %rbx, %rcx
movq %rax, %r8
callq 0x1c1a0
movq %rax, %r12
movq %rbp, %rdi
movq 0x18(%rsp), %rsi
movq 0x10(%rsp), %rbx
movq %rbx, %rdx
callq 0x2f4c6
movq 0x28(%rsp), %rax
addq %r12, %rax
subq %rax, %r14
je 0x2ece5
movq %r15, %rax
addq $0x1, (%rax)
leaq 0x8(%rax), %rax
jb 0x2ecc2
movq %rbp, %rdi
movq %rbp, %rsi
movq %r13, %rdx
movq %rbx, %rcx
callq 0x1c1c0
subq %rax, %r14
jne 0x2ecbf
movq %rax, %r12
movq %rbx, %rax
movq 0x78(%rsp), %r14
movq 0x18(%rsp), %rdi
testq %rax, %rax
jle 0x2ed0c
movq -0x8(%r13,%rax,8), %rcx
leaq -0x1(%rax), %rdx
cmpq %rcx, -0x8(%rbp,%rax,8)
movq %rdx, %rax
je 0x2ecf2
jbe 0x2ed2f
addq $0x1, (%r15)
leaq 0x8(%r15), %r15
jb 0x2ed0c
movq %rbp, %rdi
movq %rbp, %rsi
movq %r13, %rdx
movq %rbx, %rcx
callq 0x1c1c0
movq 0x18(%rsp), %rdi
movq %rax, %r12
movq 0x80(%rsp), %r15
testq %r15, %r15
jg 0x2ea5b
jmp 0x2ed56
movq 0x30(%rsp), %rax
jmp 0x2ede1
jmp 0x2ed51
movq %rax, %r12
movq 0x10(%rsp), %rbx
movq 0x20(%rsp), %rdi
movq (%rdi), %rax
leaq 0x3(%rax), %rcx
movq %rcx, (%rdi)
cmpq $-0x3, %rax
jb 0x2ed9a
movq 0x38(%rsp), %rcx
cmpq $0x2, %rcx
movl $0x1, %edx
movl $0x1, %eax
cmovgeq %rcx, %rax
xorl %ecx, %ecx
movq 0x30(%rsp), %r14
cmpq %rdx, %rax
je 0x2eda3
incq (%rdi,%rdx,8)
leaq 0x1(%rdx), %rdx
je 0x2ed89
jmp 0x2edaa
xorl %ecx, %ecx
movq 0x30(%rsp), %r14
jmp 0x2edaa
movq $-0x1, %rcx
cmpq %rcx, %r12
movl $0x1, %eax
cmoveq %r14, %rax
testq %r14, %r14
je 0x2ede1
cmpq %rcx, %r12
je 0x2ede1
cmpq $0x0, 0x38(%rsp)
jle 0x2edde
movq 0x58(%rsp), %rdx
subq %rbx, %rdx
shlq $0x3, %rdx
movl $0xff, %esi
callq 0x6170
movq %r14, %rax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x74ac
callq 0x74c5