// File: 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
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x18(%rbp), %rax
andq $0x3f, %rax
movl %eax, -0x24(%rbp)
movq -0x18(%rbp), %rax
shrq $0x6, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x20(%rbp), %rax
jl 0x57e78
movq -0x20(%rbp), %rcx
movq -0x30(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x30(%rbp)
cmpl $0x0, -0x24(%rbp)
je 0x57d4b
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
xorl %eax, %eax
subq -0x30(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
movq -0x30(%rbp), %rdx
addq $0x1, %rdx
movl -0x24(%rbp), %ecx
callq 0x37320
movq -0x8(%rbp), %rax
movq -0x30(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rdx
subq -0x30(%rbp), %rdx
movl -0x24(%rbp), %ecx
callq 0x5da20
movq %rax, -0x38(%rbp)
jmp 0x57dbe
jmp 0x57d4d
jmp 0x57d4f
jmp 0x57d51
jmp 0x57d53
jmp 0x57d55
jmp 0x57d57
jmp 0x57d59
jmp 0x57d5b
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
xorl %eax, %eax
subq -0x30(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
movq -0x30(%rbp), %rdx
callq 0x554c6
jmp 0x57d86
movq -0x10(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rdx
subq -0x30(%rbp), %rdx
callq 0x37180
movq $0x0, -0x38(%rbp)
movq -0x8(%rbp), %rax
movq -0x20(%rbp), %rcx
movq $0x0, (%rax,%rcx,8)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rax
movq -0x38(%rbp), %rcx
addq %rcx, (%rax)
jae 0x57df2
addq $0x1, 0x8(%rax)
leaq 0x8(%rax), %rax
jb 0x57de7
movq %rax, -0x48(%rbp)
jmp 0x57df8
jmp 0x57dfa
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0x57e18
movl $0x1, %eax
movq %rax, -0x58(%rbp)
jmp 0x57e20
movq -0x40(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rax
movq -0x30(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
cmpq $0x0, -0x40(%rbp)
sete %cl
andb $0x1, %cl
movzbl %cl, %ecx
movslq %ecx, %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq -0x38(%rbp), %rcx
addq %rcx, (%rax)
jae 0x57e6b
addq $0x1, 0x8(%rax)
leaq 0x8(%rax), %rax
jb 0x57e60
movq %rax, -0x50(%rbp)
jmp 0x57e71
jmp 0x57e73
jmp 0x5807d
cmpl $0x0, -0x24(%rbp)
je 0x57eeb
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
xorl %eax, %eax
subq -0x30(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
movq -0x30(%rbp), %rdx
addq $0x1, %rdx
movl -0x24(%rbp), %ecx
callq 0x5da20
movq -0x8(%rbp), %rax
movq -0x30(%rbp), %rcx
movq (%rax,%rcx,8), %rax
xorq $-0x1, %rax
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rdx
subq -0x30(%rbp), %rdx
movl -0x24(%rbp), %ecx
callq 0x37320
movq %rax, -0x38(%rbp)
jmp 0x57f60
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
xorl %eax, %eax
subq -0x30(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
movq -0x30(%rbp), %rdx
addq $0x1, %rdx
callq 0x37180
movq -0x10(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x40(%rbp)
jmp 0x57f2a
jmp 0x57f2c
jmp 0x57f2e
jmp 0x57f30
jmp 0x57f32
jmp 0x57f34
jmp 0x57f36
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rdx
subq -0x30(%rbp), %rdx
callq 0x554c6
jmp 0x57f58
movq $0x0, -0x38(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x57fb3
movq -0x38(%rbp), %rax
movq %rax, %rcx
addq $-0x1, %rcx
movq %rcx, -0x38(%rbp)
cmpq $0x0, %rax
jne 0x57f96
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rsi
movq -0x20(%rbp), %rdx
movl $0x1, %ecx
callq 0x564f0
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rsi
movq -0x30(%rbp), %rdx
movq -0x38(%rbp), %rcx
callq 0x36e60
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
movq -0x8(%rbp), %rsi
movq -0x30(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
movq -0x20(%rbp), %rdx
subq -0x30(%rbp), %rdx
movq -0x38(%rbp), %rcx
callq 0x36e60
xorl %ecx, %ecx
movl %ecx, %edx
subq %rax, %rdx
movq -0x8(%rbp), %rax
movq -0x20(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
movq -0x8(%rbp), %rsi
movq -0x30(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
movq -0x20(%rbp), %rdx
subq -0x30(%rbp), %rdx
movq -0x40(%rbp), %rcx
callq 0x36e60
movq %rax, %rsi
movq -0x8(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
subq %rsi, %rdx
movq %rdx, (%rax,%rcx,8)
movq -0x8(%rbp), %rcx
movq -0x20(%rbp), %rdx
movabsq $-0x8000000000000000, %rax # imm = 0x8000000000000000
andq (%rcx,%rdx,8), %rax
cmpq $0x0, %rax
je 0x5807b
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rsi
movq -0x20(%rbp), %rdx
movl $0x1, %ecx
callq 0x564f0
movq %rax, %rdx
movq -0x8(%rbp), %rax
movq -0x20(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
jmp 0x5807d
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)