// File: /workspace/github_cpp_makefile_star2_O1/marxn[P]pupp/3rdparty/gmp/mpn/mu_div_qr.c
// Function: _gmpn_preinv_mu_div_qr
mp_limb_t
mpn_preinv_mu_div_qr (mp_ptr qp,
		      mp_ptr rp,
		      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 tp           scratch
#define scratch_out  (scratch + 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_INCR (rp, np, dn);

  /* if (qn == 0) */			/* The while below handles this case */
  /*   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;

      /* 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+1 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");
	      }
	    );
    }

  return qh;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %r9, %rbx
movq %r8, %r14
movq %rsi, %r15
movq 0xa8(%rsp), %r13
movq 0xa0(%rsp), %rax
movq %rax, 0x40(%rsp)
leaq (%rdx,%rcx,8), %rax
addq $-0x8, %rax
movq %rcx, %rbp
subq %r9, %rbp
leaq (%rdx,%rbp,8), %rsi
leaq (%rdi,%rbp,8), %r12
movq %r9, %rcx
testq %rcx, %rcx
jle 0x2e2e2
movq -0x8(%r14,%rcx,8), %rdx
decq %rcx
leaq -0x8(%rax), %rdi
cmpq %rdx, (%rax)
movq %rdi, %rax
je 0x2e2c4
seta %al
jmp 0x2e2e4
movb $0x1, %al
movb %al, 0x17(%rsp)
testb %al, %al
movq %rsi, 0x38(%rsp)
movq %r15, %rdi
je 0x2e301
movq %r14, %rdx
movq %rbx, %rcx
callq 0x1c1c0
jmp 0x2e309
movq %rbx, %rdx
callq 0x2f4c6
testq %rbp, %rbp
jle 0x2e5f1
leaq (%r15,%rbx,8), %rax
movq %rax, 0x30(%rsp)
leaq 0x1(%rbx), %rax
movq %rax, 0x50(%rsp)
leaq -0x8(%r15), %rax
movq %rax, 0x48(%rsp)
movq %rbx, %rax
negq %rax
movq %rax, 0x28(%rsp)
movq %r13, %rax
movq %rbp, %rcx
subq %r13, %rcx
cmovlq %rbp, %r13
movq %r13, 0x18(%rsp)
negq %rcx
movq %rbp, 0x60(%rsp)
cmpq %rbp, %rax
movl $0x0, %eax
cmovleq %rax, %rcx
movq 0x40(%rsp), %rdx
leaq (%rdx,%rcx,8), %rdx
leaq (,%r13,8), %rax
subq %rax, %r12
movq 0x30(%rsp), %r13
movq %rax, 0x20(%rsp)
subq %rax, %r13
movq 0xb0(%rsp), %rbp
movq %rbp, %rdi
movq %r13, %rsi
movq %rdx, 0x40(%rsp)
movq 0x18(%rsp), %rcx
callq 0x1d864
movq 0x18(%rsp), %rax
leaq (%rbp,%rax,8), %rbp
movq %r12, %rdi
movq %rbp, %rsi
movq %r13, %rdx
movq 0x18(%rsp), %r13
movq %r13, %rcx
callq 0x1bfa0
testq %rax, %rax
jne 0x2e605
movq %rbp, 0x58(%rsp)
cmpq $0x20, %r13
jle 0x2e480
movq 0x50(%rsp), %rdi
callq 0x2aee3
movq %rax, %rbp
movq 0xb0(%rsp), %rdi
leaq (%rdi,%rax,8), %rax
movq %rax, (%rsp)
movq %rbp, %rsi
movq %r14, %rdx
movq %rbx, %rcx
movq %r12, %r8
movq %r13, %r9
callq 0x2a886
movq 0xb0(%rsp), %r8
movq %r13, %rcx
addq %rbx, %r13
subq %rbp, %r13
testq %r13, %r13
jle 0x2e508
leaq (,%r13,8), %rax
movq 0x30(%rsp), %rdx
subq %rax, %rdx
movq %r8, %rdi
movq %r8, %rsi
movq %r13, %rcx
callq 0x1c1c0
movq 0xb0(%rsp), %rcx
subq %rax, (%rcx,%r13,8)
jae 0x2e4a4
leaq (%rcx,%r13,8), %rcx
movq %rbp, %rdx
subq %r13, %rdx
cmpq $0x2, %rdx
movl $0x1, %eax
cmovlq %rax, %rdx
movl $0x1, %esi
movq 0x28(%rsp), %r8
cmpq %rsi, %rdx
je 0x2e4ab
subq $0x1, (%rcx,%rsi,8)
leaq 0x1(%rsi), %rsi
jb 0x2e46c
xorl %eax, %eax
jmp 0x2e4ab
movq 0xb0(%rsp), %rbp
movq %rbp, %rdi
movq %r14, %rsi
movq %rbx, %rdx
movq %r12, %rcx
movq %r13, %r8
callq 0x1cd58
movq %rbp, %r8
movq %r13, %rcx
jmp 0x2e508
xorl %eax, %eax
movq 0x28(%rsp), %r8
movq 0x48(%rsp), %rcx
subq 0x20(%rsp), %rcx
movq 0xb0(%rsp), %rdi
leaq (%r8,%rbp), %rdx
testq %rdx, %rdx
jle 0x2e4e0
movq -0x8(%rdi,%rbp,8), %rdx
leaq -0x1(%rbp), %rsi
cmpq %rdx, (%rcx,%rbp,8)
movq %rsi, %rbp
je 0x2e4bd
setbe %cl
movzbl %cl, %ecx
jmp 0x2e4e2
xorl %ecx, %ecx
cmpl %eax, %ecx
jb 0x2e60a
subq %rax, %rcx
movq %rdi, %rax
addq %rcx, (%rax)
jae 0x2e500
addq $0x1, 0x8(%rax)
leaq 0x8(%rax), %rax
jb 0x2e4f5
movq %rdi, %r8
movq 0x18(%rsp), %rcx
movq 0x38(%rsp), %rsi
subq 0x20(%rsp), %rsi
movq %rbx, %r13
movq (%r8,%rbx,8), %rax
movq %rax, 0x20(%rsp)
subq %rcx, %r13
movq (%r15,%r13,8), %rbp
movq %rsi, 0x38(%rsp)
jne 0x2e53c
movq %r15, %rdi
movq %r8, %rdx
callq 0x1c1c0
movq %rax, %r13
jmp 0x2e573
movq %r8, %rdi
movq %r8, %rdx
callq 0x1c1c0
movq 0x58(%rsp), %rdi
movq %r15, %rsi
movq %rdi, %rdx
movq %r13, %rcx
movq %rax, %r8
callq 0x1c1a0
movq %rax, %r13
movq %r15, %rdi
movq 0xb0(%rsp), %rsi
movq %rbx, %rdx
callq 0x2f4c6
movq 0x20(%rsp), %rax
addq %r13, %rax
subq %rax, %rbp
je 0x2e5a0
movq %r12, %rax
addq $0x1, (%rax)
leaq 0x8(%rax), %rax
jb 0x2e583
movq %r15, %rdi
movq %r15, %rsi
movq %r14, %rdx
movq %rbx, %rcx
callq 0x1c1c0
jmp 0x2e57b
movq 0x18(%rsp), %r13
movq 0x60(%rsp), %rbp
subq %r13, %rbp
movq %rbx, %rax
testq %rax, %rax
jle 0x2e5ca
movq -0x8(%r14,%rax,8), %rcx
leaq -0x1(%rax), %rdx
cmpq %rcx, -0x8(%r15,%rax,8)
movq %rdx, %rax
je 0x2e5b0
jbe 0x2e5e8
movq %r12, %rax
addq $0x1, (%rax)
leaq 0x8(%rax), %rax
jb 0x2e5cd
movq %r15, %rdi
movq %r15, %rsi
movq %r14, %rdx
movq %rbx, %rcx
callq 0x1c1c0
testq %rbp, %rbp
jg 0x2e338
movzbl 0x17(%rsp), %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x747a
callq 0x7493