// File: /workspace/github_cpp_makefile_star2_O2/marxn[P]pupp/3rdparty/gmp/mpn/mul_fft.c
// Function: mpn_fft_mul_2exp_modF
static void
mpn_fft_mul_2exp_modF (mp_ptr r, mp_srcptr a, mp_bitcnt_t d, mp_size_t n)
{
  unsigned int sh;
  mp_size_t m;
  mp_limb_t cc, rd;

  sh = d % GMP_NUMB_BITS;
  m = d / GMP_NUMB_BITS;

  if (m >= n)			/* negate */
    {
      /* r[0..m-1]  <-- lshift(a[n-m]..a[n-1], sh)
	 r[m..n-1]  <-- -lshift(a[0]..a[n-m-1],  sh) */

      m -= n;
      if (sh != 0)
	{
	  /* no out shift below since a[n] <= 1 */
	  mpn_lshift (r, a + n - m, m + 1, sh);
	  rd = r[m];
	  cc = mpn_lshiftc (r + m, a, n - m, sh);
	}
      else
	{
	  MPN_COPY (r, a + n - m, m);
	  rd = a[n];
	  mpn_com (r + m, a, n - m);
	  cc = 0;
	}

      /* add cc to r[0], and add rd to r[m] */

      /* now add 1 in r[m], subtract 1 in r[n], i.e. add 1 in r[0] */

      r[n] = 0;
      /* cc < 2^sh <= 2^(GMP_NUMB_BITS-1) thus no overflow here */
      cc++;
      mpn_incr_u (r, cc);

      rd++;
      /* rd might overflow when sh=GMP_NUMB_BITS-1 */
      cc = (rd == 0) ? 1 : rd;
      r = r + m + (rd == 0);
      mpn_incr_u (r, cc);
    }
  else
    {
      /* r[0..m-1]  <-- -lshift(a[n-m]..a[n-1], sh)
	 r[m..n-1]  <-- lshift(a[0]..a[n-m-1],  sh)  */
      if (sh != 0)
	{
	  /* no out bits below since a[n] <= 1 */
	  mpn_lshiftc (r, a + n - m, m + 1, sh);
	  rd = ~r[m];
	  /* {r, m+1} = {a+n-m, m+1} << sh */
	  cc = mpn_lshift (r + m, a, n - m, sh); /* {r+m, n-m} = {a, n-m}<<sh */
	}
      else
	{
	  /* r[m] is not used below, but we save a test for m=0 */
	  mpn_com (r, a + n - m, m + 1);
	  rd = a[n];
	  MPN_COPY (r + m, a, n - m);
	  cc = 0;
	}

      /* now complement {r, m}, subtract cc from r[0], subtract rd from r[m] */

      /* if m=0 we just have r[0]=a[n] << sh */
      if (m != 0)
	{
	  /* now add 1 in r[0], subtract 1 in r[m] */
	  if (cc-- == 0) /* then add 1 to r[0] */
	    cc = mpn_add_1 (r, r, n, CNST_LIMB(1));
	  cc = mpn_sub_1 (r, r, m, cc) + 1;
	  /* add 1 to cc instead of rd since rd might overflow */
	}

      /* now subtract cc and rd from r[m..n] */

      r[n] = -mpn_sub_1 (r + m, r + m, n - m, cc);
      r[n] -= mpn_sub_1 (r + m, r + m, n - m, rd);
      if (r[n] & GMP_LIMB_HIGHBIT)
	r[n] = mpn_add_1 (r, r, n, CNST_LIMB(1));
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, %r14
movq %rsi, %rbp
movq %rdi, %rbx
movl %r14d, %r13d
andl $0x3f, %r13d
movq %rdx, %r15
shrq $0x6, %r15
movq %rcx, %r12
subq %r15, %r12
jle 0x2b3ea
movq %rbp, 0x8(%rsp)
leaq (,%rcx,8), %rsi
addq %rbp, %rsi
leaq (,%r15,8), %rax
subq %rax, %rsi
leaq 0x1(%r15), %rdx
testl %r13d, %r13d
movq %rcx, 0x10(%rsp)
je 0x2b445
movq %rbx, %rdi
movl %r13d, %ecx
callq 0x2dbc0
leaq (%rbx,%r15,8), %rdi
movq (%rdi), %rbp
notq %rbp
movq 0x8(%rsp), %rsi
movq %r12, %rdx
movl %r13d, %ecx
callq 0x181a0
movq %rax, %rcx
cmpq $0x40, %r14
jb 0x2b50c
subq $0x1, %rcx
jb 0x2b4e2
jmp 0x2b4f8
subq %rcx, %r15
leaq (,%rcx,8), %rsi
addq %rbp, %rsi
movq %rcx, %r12
leaq (,%r15,8), %rax
subq %rax, %rsi
leaq (%rbx,%r15,8), %rax
movq %rax, 0x8(%rsp)
testl %r13d, %r13d
je 0x2b47b
leaq 0x1(%r15), %rdx
movq %rbx, %rdi
movl %r13d, %ecx
callq 0x181a0
movq (%rbx,%r15,8), %r14
movq %r12, %rdx
subq %r15, %rdx
movq 0x8(%rsp), %r15
movq %r15, %rdi
movq %rbp, %rsi
movl %r13d, %ecx
callq 0x2dbc0
incq %rax
jmp 0x2b4a4
movq %rcx, %rbp
movq %rbx, %rdi
callq 0x18000
movq 0x8(%rsp), %rsi
movq (%rsi,%rbp,8), %r13
leaq (%rbx,%r15,8), %rdi
movq %rbp, %r12
subq %r15, %r12
movq %r12, %rdx
callq 0x290c6
cmpq $0x40, %r14
jae 0x2b4df
xorl %ecx, %ecx
movq %r13, %rbp
jmp 0x2b50c
movq %rbx, %rdi
movq %r15, %rdx
callq 0x290c6
movq (%rbp,%r12,8), %r14
movq %r12, %rdx
subq %r15, %rdx
movq 0x8(%rsp), %r15
movq %r15, %rdi
movq %rbp, %rsi
callq 0x18000
pushq $0x1
popq %rax
andq $0x0, (%rbx,%r12,8)
addq %rax, (%rbx)
jae 0x2b4b9
addq $0x1, 0x8(%rbx)
leaq 0x8(%rbx), %rbx
jb 0x2b4ae
xorl %eax, %eax
incq %r14
sete %al
leaq (%r15,%rax,8), %rax
cmpq $0x1, %r14
adcq $0x0, %r14
addq %r14, (%rax)
jae 0x2b4dd
addq $0x1, 0x8(%rax)
leaq 0x8(%rax), %rax
jb 0x2b4d2
jmp 0x2b556
movq %r13, %rbp
pushq $0x1
popq %rcx
movq %rbx, %rdi
movq %rbx, %rsi
movq 0x10(%rsp), %rdx
callq 0x29e1c
movq %rax, %rcx
movq %rbx, %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x17e44
movq %rax, %rcx
incq %rcx
leaq (%rbx,%r15,8), %r14
movq %r14, %rdi
movq %r14, %rsi
movq %r12, %rdx
callq 0x17e44
negq %rax
movq 0x10(%rsp), %r15
movq %rax, (%rbx,%r15,8)
movq %r14, %rdi
movq %r14, %rsi
movq %r12, %rdx
movq %rbp, %rcx
callq 0x17e44
subq %rax, (%rbx,%r15,8)
jns 0x2b556
movq %r15, %rdx
pushq $0x1
popq %rcx
movq %rbx, %rdi
movq %rbx, %rsi
callq 0x29e1c
movq %rax, (%rbx,%r15,8)
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq