// File: /workspace/github_cpp_makefile_star2_O3/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, %rbp
movq %r8, %r15
movq %rcx, %r13
movq %rdx, %rbx
movq 0xc8(%rsp), %r12
movq 0xc0(%rsp), %rax
movq %rax, 0x48(%rsp)
movq %rdx, %rax
subq %r8, %rax
leaq (%rsi,%rax,8), %r8
movq %rax, 0x10(%rsp)
leaq (%rdi,%rax,8), %r14
leaq (%rsi,%rdx,8), %rax
addq $-0x8, %rax
movq %r15, %rcx
movq %r8, 0x40(%rsp)
testq %rcx, %rcx
jle 0x2e622
movq -0x8(%r13,%rcx,8), %rdx
decq %rcx
leaq -0x8(%rax), %rsi
cmpq %rdx, (%rax)
movq %rsi, %rax
je 0x2e607
jbe 0x2e641
movq %r12, %rdi
movq %r8, %rsi
movq %r13, %rdx
movq %r15, %rcx
callq 0x1bca0
movl $0x1, %eax
movq %rax, 0x8(%rsp)
xorl %eax, %eax
jmp 0x2e65a
movq %r12, %rdi
movq %r8, %rsi
movq %r15, %rdx
callq 0x2f106
movb $0x1, %al
movq $0x0, 0x8(%rsp)
cmpq $0x0, 0x10(%rsp)
je 0x2e96b
movq %rbx, 0x50(%rsp)
movl %eax, 0x3c(%rsp)
jle 0x2e975
leaq (%r12,%r15,8), %rax
movq %rax, 0x28(%rsp)
leaq 0x1(%r15), %rax
movq %rax, 0x68(%rsp)
leaq -0x8(%r12), %rax
movq %rax, 0x60(%rsp)
movq %r15, %rax
negq %rax
movq %rax, 0x58(%rsp)
movq 0x10(%rsp), %r8
movq %rbp, %r12
movq %r15, 0x18(%rsp)
movq %r14, %r15
movq 0x48(%rsp), %r14
movq %r14, %rax
movq %r8, %rcx
subq %r14, %rcx
cmovlq %r8, %r14
negq %rcx
cmpq %r8, %rax
movl $0x0, %eax
cmovleq %rax, %rcx
leaq (%r12,%rcx,8), %rdx
leaq (,%r14,8), %rax
subq %rax, %r15
movq 0x28(%rsp), %r12
movq %r12, %rbx
movq %rax, 0x20(%rsp)
subq %rax, %rbx
movq %r12, %rdi
movq %rbx, %rsi
movq %r8, %rbp
movq %rdx, 0x80(%rsp)
movq %r14, %rcx
callq 0x1d348
leaq (%r12,%r14,8), %r12
movq %r15, 0x30(%rsp)
movq %r15, %rdi
movq %r12, %rsi
movq %rbx, %rdx
movq %r14, %rcx
callq 0x1ba80
testq %rax, %rax
jne 0x2ea2a
subq %r14, %rbp
je 0x2e977
movq %r12, 0x70(%rsp)
movq %rbp, 0x78(%rsp)
cmpq $0x20, %r14
jle 0x2e81a
movq 0x68(%rsp), %rdi
callq 0x2ab71
movq %rax, %rbx
movq 0x28(%rsp), %r12
leaq (%r12,%rax,8), %rax
movq %rax, (%rsp)
movq %r12, %rdi
movq %rbx, %rsi
movq %r13, %rdx
movq 0x18(%rsp), %r15
movq %r15, %rcx
movq 0x30(%rsp), %r8
movq %r14, %r9
callq 0x2a51a
movq %r12, %rdx
leaq (%r14,%r15), %r12
subq %rbx, %r12
testq %r12, %r12
movq 0xc8(%rsp), %rbp
jle 0x2e86f
leaq (,%r12,8), %rax
movq %rdx, %r15
subq %rax, %rdx
movq %r15, %rdi
movq %r15, %rsi
movq %r12, %rcx
callq 0x1bca0
subq %rax, (%r15,%r12,8)
movq 0x58(%rsp), %r8
jae 0x2e7eb
leaq (%r15,%r12,8), %rcx
movq %rbx, %rdx
subq %r12, %rdx
cmpq $0x2, %rdx
movl $0x1, %eax
cmovlq %rax, %rdx
movl $0x1, %esi
cmpq %rsi, %rdx
je 0x2e7ed
subq $0x1, (%rcx,%rsi,8)
leaq 0x1(%rsi), %rsi
jb 0x2e7db
xorl %eax, %eax
movq 0x60(%rsp), %rcx
subq 0x20(%rsp), %rcx
leaq (%r8,%rbx), %rdx
testq %rdx, %rdx
jle 0x2e847
movq -0x8(%r15,%rbx,8), %rdx
leaq -0x1(%rbx), %rsi
cmpq %rdx, (%rcx,%rbx,8)
movq %rsi, %rbx
je 0x2e7f7
setbe %cl
movzbl %cl, %ecx
jmp 0x2e849
movq 0x28(%rsp), %rbx
movq %rbx, %rdi
movq %r13, %rsi
movq 0x18(%rsp), %r15
movq %r15, %rdx
movq 0x30(%rsp), %rcx
movq %r14, %r8
callq 0x1c838
movq %rbx, %rdx
movq 0xc8(%rsp), %rbp
jmp 0x2e86f
xorl %ecx, %ecx
cmpl %eax, %ecx
jb 0x2ea2f
subq %rax, %rcx
movq %r15, %rax
addq %rcx, (%rax)
jae 0x2e867
addq $0x1, 0x8(%rax)
leaq 0x8(%rax), %rax
jb 0x2e85c
movq %r15, %rdx
movq 0x18(%rsp), %r15
movq 0x40(%rsp), %rsi
subq 0x20(%rsp), %rsi
movq %r15, %rbx
movq (%rdx,%r15,8), %rax
movq %rax, 0x20(%rsp)
subq %r14, %rbx
movq (%rbp,%rbx,8), %r12
movq %r14, 0x48(%rsp)
movq %rsi, 0x40(%rsp)
jne 0x2e8a9
movq %rbp, %rdi
movq %r15, %rcx
callq 0x1bca0
movq %rax, %rbx
jmp 0x2e8dd
movq %rdx, %rdi
movq %r14, %rcx
callq 0x1bca0
movq 0x70(%rsp), %rdi
movq %rbp, %rsi
movq %rdi, %rdx
movq %rbx, %rcx
movq %rax, %r8
callq 0x1bc80
movq %rax, %rbx
movq %rbp, %rdi
movq 0x28(%rsp), %rsi
movq %r15, %rdx
callq 0x2f106
movq 0x20(%rsp), %rax
addq %rbx, %rax
subq %rax, %r12
movq 0x30(%rsp), %r14
je 0x2e915
movq %r14, %rax
addq $0x1, (%rax)
leaq 0x8(%rax), %rax
jb 0x2e8f2
movq %rbp, %rdi
movq %rbp, %rsi
movq %r13, %rdx
movq %r15, %rcx
callq 0x1bca0
subq %rax, %r12
jne 0x2e8ef
movq %rax, %rbx
movq %r15, %rax
movq 0x80(%rsp), %r12
testq %rax, %rax
jle 0x2e93a
movq -0x8(%r13,%rax,8), %rcx
leaq -0x1(%rax), %rdx
cmpq %rcx, -0x8(%rbp,%rax,8)
movq %rdx, %rax
je 0x2e920
jbe 0x2e95b
movq %r14, %rax
addq $0x1, (%rax)
leaq 0x8(%rax), %rax
jb 0x2e93d
movq %rbp, %rdi
movq %rbp, %rsi
movq %r13, %rdx
movq %r15, %rcx
callq 0x1bca0
movq %rax, %rbx
movq 0x78(%rsp), %r8
testq %r8, %r8
jg 0x2e6a9
jmp 0x2e983
movq 0x8(%rsp), %rax
jmp 0x2ea18
jmp 0x2e983
xorl %ebx, %ebx
movq 0x18(%rsp), %r15
movq 0x30(%rsp), %r14
movq (%r14), %rax
leaq 0x3(%rax), %rcx
movq %rcx, (%r14)
cmpq $-0x3, %rax
jb 0x2e9c2
movq 0x10(%rsp), %rcx
cmpq $0x2, %rcx
movl $0x1, %edx
movl $0x1, %eax
cmovgeq %rcx, %rax
xorl %ecx, %ecx
movq 0x8(%rsp), %r12
cmpq %rdx, %rax
je 0x2e9cb
incq (%r14,%rdx,8)
leaq 0x1(%rdx), %rdx
je 0x2e9b1
jmp 0x2e9d2
xorl %ecx, %ecx
movq 0x8(%rsp), %r12
jmp 0x2e9d2
movq $-0x1, %rcx
cmpq $0x0, 0x10(%rsp)
setle %dl
movl 0x3c(%rsp), %esi
testb %sil, %sil
movl $0x1, %eax
cmoveq %r12, %rax
cmpq %rcx, %rbx
sete %cl
cmoveq %r12, %rax
orb %sil, %dl
orb %cl, %dl
jne 0x2ea18
movq 0x50(%rsp), %rdx
subq %r15, %rdx
shlq $0x3, %rdx
movq %r14, %rdi
movl $0xff, %esi
callq 0x6170
movq %r12, %rax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x7462
callq 0x747b