// File: /workspace/github_cpp_makefile_star2_O3/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
movq %rsi, 0x38(%rsp)
testq %rcx, %rcx
jle 0x2df26
movq -0x8(%r14,%rcx,8), %rdx
decq %rcx
leaq -0x8(%rax), %rdi
cmpq %rdx, (%rax)
movq %rdi, %rax
je 0x2df0b
jbe 0x2df40
movq %r15, %rdi
movq %r14, %rdx
movq %rbx, %rcx
callq 0x1bca0
movl $0x1, %eax
movq %rax, 0x20(%rsp)
jmp 0x2df54
movq %r15, %rdi
movq %rbx, %rdx
callq 0x2f106
movq $0x0, 0x20(%rsp)
testq %rbp, %rbp
jle 0x2e23f
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, 0x10(%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, 0x18(%rsp)
subq %rax, %r13
movq 0xb0(%rsp), %rbp
movq %rbp, %rdi
movq %r13, %rsi
movq %rdx, 0x40(%rsp)
movq 0x10(%rsp), %rcx
callq 0x1d348
movq 0x10(%rsp), %rax
leaq (%rbp,%rax,8), %rbp
movq %r12, %rdi
movq %rbp, %rsi
movq %r13, %rdx
movq 0x10(%rsp), %r13
movq %r13, %rcx
callq 0x1ba80
testq %rax, %rax
jne 0x2e253
movq %rbp, 0x58(%rsp)
cmpq $0x20, %r13
jle 0x2e0cb
movq 0x50(%rsp), %rdi
callq 0x2ab71
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 0x2a51a
movq 0xb0(%rsp), %r8
movq %r13, %rcx
addq %rbx, %r13
subq %rbp, %r13
testq %r13, %r13
jle 0x2e153
leaq (,%r13,8), %rax
movq 0x30(%rsp), %rdx
subq %rax, %rdx
movq %r8, %rdi
movq %r8, %rsi
movq %r13, %rcx
callq 0x1bca0
movq 0xb0(%rsp), %rcx
subq %rax, (%rcx,%r13,8)
jae 0x2e0ef
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 0x2e0f6
subq $0x1, (%rcx,%rsi,8)
leaq 0x1(%rsi), %rsi
jb 0x2e0b7
xorl %eax, %eax
jmp 0x2e0f6
movq 0xb0(%rsp), %rbp
movq %rbp, %rdi
movq %r14, %rsi
movq %rbx, %rdx
movq %r12, %rcx
movq %r13, %r8
callq 0x1c838
movq %rbp, %r8
movq %r13, %rcx
jmp 0x2e153
xorl %eax, %eax
movq 0x28(%rsp), %r8
movq 0x48(%rsp), %rcx
subq 0x18(%rsp), %rcx
movq 0xb0(%rsp), %rdi
leaq (%r8,%rbp), %rdx
testq %rdx, %rdx
jle 0x2e12b
movq -0x8(%rdi,%rbp,8), %rdx
leaq -0x1(%rbp), %rsi
cmpq %rdx, (%rcx,%rbp,8)
movq %rsi, %rbp
je 0x2e108
setbe %cl
movzbl %cl, %ecx
jmp 0x2e12d
xorl %ecx, %ecx
cmpl %eax, %ecx
jb 0x2e258
subq %rax, %rcx
movq %rdi, %rax
addq %rcx, (%rax)
jae 0x2e14b
addq $0x1, 0x8(%rax)
leaq 0x8(%rax), %rax
jb 0x2e140
movq %rdi, %r8
movq 0x10(%rsp), %rcx
movq 0x38(%rsp), %rsi
subq 0x18(%rsp), %rsi
movq %rbx, %r13
movq (%r8,%rbx,8), %rax
movq %rax, 0x18(%rsp)
subq %rcx, %r13
movq (%r15,%r13,8), %rbp
movq %rsi, 0x38(%rsp)
jne 0x2e18a
movq %r15, %rdi
movq %r8, %rdx
movq %rbx, %rcx
callq 0x1bca0
movq %rax, %r13
jmp 0x2e1c1
movq %r8, %rdi
movq %r8, %rdx
callq 0x1bca0
movq 0x58(%rsp), %rdi
movq %r15, %rsi
movq %rdi, %rdx
movq %r13, %rcx
movq %rax, %r8
callq 0x1bc80
movq %rax, %r13
movq %r15, %rdi
movq 0xb0(%rsp), %rsi
movq %rbx, %rdx
callq 0x2f106
movq 0x18(%rsp), %rax
addq %r13, %rax
subq %rax, %rbp
je 0x2e1ee
movq %r12, %rax
addq $0x1, (%rax)
leaq 0x8(%rax), %rax
jb 0x2e1d1
movq %r15, %rdi
movq %r15, %rsi
movq %r14, %rdx
movq %rbx, %rcx
callq 0x1bca0
jmp 0x2e1c9
movq 0x10(%rsp), %r13
movq 0x60(%rsp), %rbp
subq %r13, %rbp
movq %rbx, %rax
testq %rax, %rax
jle 0x2e218
movq -0x8(%r14,%rax,8), %rcx
leaq -0x1(%rax), %rdx
cmpq %rcx, -0x8(%r15,%rax,8)
movq %rdx, %rax
je 0x2e1fe
jbe 0x2e236
movq %r12, %rax
addq $0x1, (%rax)
leaq 0x8(%rax), %rax
jb 0x2e21b
movq %r15, %rdi
movq %r15, %rsi
movq %r14, %rdx
movq %rbx, %rcx
callq 0x1bca0
testq %rbp, %rbp
jg 0x2df83
movq 0x20(%rsp), %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x7430
callq 0x7449