// File: /workspace/github_cpp_makefile_star2_O2/marxn[P]pupp/3rdparty/gmp/mpn/toom_eval_pm2exp.c
// Function: _gmpn_toom_eval_pm2exp
int
mpn_toom_eval_pm2exp (mp_ptr xp2, mp_ptr xm2, unsigned k,
		      mp_srcptr xp, mp_size_t n, mp_size_t hn, unsigned shift,
		      mp_ptr tp)
{
  unsigned i;
  int neg;
#if HAVE_NATIVE_mpn_addlsh_n
  mp_limb_t cy;
#endif

  ASSERT (k >= 3);
  ASSERT (shift*k < GMP_NUMB_BITS);

  ASSERT (hn > 0);
  ASSERT (hn <= n);

  /* The degree k is also the number of full-size coefficients, so
   * that last coefficient, of size hn, starts at xp + k*n. */

#if HAVE_NATIVE_mpn_addlsh_n
  xp2[n] = mpn_addlsh_n (xp2, xp, xp + 2*n, n, 2*shift);
  for (i = 4; i < k; i += 2)
    xp2[n] += mpn_addlsh_n (xp2, xp2, xp + i*n, n, i*shift);

  tp[n] = mpn_lshift (tp, xp+n, n, shift);
  for (i = 3; i < k; i+= 2)
    tp[n] += mpn_addlsh_n (tp, tp, xp+i*n, n, i*shift);

  if (k & 1)
    {
      cy = mpn_addlsh_n (tp, tp, xp+k*n, hn, k*shift);
      MPN_INCR_U (tp + hn, n+1 - hn, cy);
    }
  else
    {
      cy = mpn_addlsh_n (xp2, xp2, xp+k*n, hn, k*shift);
      MPN_INCR_U (xp2 + hn, n+1 - hn, cy);
    }

#else /* !HAVE_NATIVE_mpn_addlsh_n */
  xp2[n] = mpn_lshift (tp, xp+2*n, n, 2*shift);
  xp2[n] += mpn_add_n (xp2, xp, tp, n);
  for (i = 4; i < k; i += 2)
    {
      xp2[n] += mpn_lshift (tp, xp + i*n, n, i*shift);
      xp2[n] += mpn_add_n (xp2, xp2, tp, n);
    }

  tp[n] = mpn_lshift (tp, xp+n, n, shift);
  for (i = 3; i < k; i+= 2)
    {
      tp[n] += mpn_lshift (xm2, xp + i*n, n, i*shift);
      tp[n] += mpn_add_n (tp, tp, xm2, n);
    }

  xm2[hn] = mpn_lshift (xm2, xp + k*n, hn, k*shift);
  if (k & 1)
    mpn_add (tp, tp, n+1, xm2, hn+1);
  else
    mpn_add (xp2, xp2, n+1, xm2, hn+1);
#endif /* !HAVE_NATIVE_mpn_addlsh_n */

  neg = (mpn_cmp (xp2, tp, n + 1) < 0) ? ~0 : 0;

#if HAVE_NATIVE_mpn_add_n_sub_n
  if (neg)
    mpn_add_n_sub_n (xp2, xm2, tp, xp2, n + 1);
  else
    mpn_add_n_sub_n (xp2, xm2, xp2, tp, n + 1);
#else /* !HAVE_NATIVE_mpn_add_n_sub_n */
  if (neg)
    mpn_sub_n (xm2, tp, xp2, n + 1);
  else
    mpn_sub_n (xm2, xp2, tp, n + 1);

  mpn_add_n (xp2, xp2, tp, n + 1);
#endif /* !HAVE_NATIVE_mpn_add_n_sub_n */

  /* FIXME: the following asserts are useless if (k+1)*shift >= GMP_LIMB_BITS */
  ASSERT ((k+1)*shift >= GMP_LIMB_BITS ||
	  xp2[n] < ((CNST_LIMB(1)<<((k+1)*shift))-1)/((CNST_LIMB(1)<<shift)-1));
  ASSERT ((k+2)*shift >= GMP_LIMB_BITS ||
	  xm2[n] < ((CNST_LIMB(1)<<((k+2)*shift))-((k&1)?(CNST_LIMB(1)<<shift):1))/((CNST_LIMB(1)<<(2*shift))-1));

  return neg;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r9, 0x18(%rsp)
movq %r8, %rbx
movl %edx, %r12d
movq %rsi, 0x20(%rsp)
movq %rdi, %r14
movl 0x60(%rsp), %r15d
movq %r8, %rdx
shlq $0x4, %rdx
addq %rcx, %rdx
leal (%r15,%r15), %ebp
movq %rcx, 0x8(%rsp)
movq %rcx, %rsi
movq %r8, %rcx
movl %ebp, %r8d
callq 0x298b0
movq %rax, (%r14,%rbx,8)
leal (,%r15,4), %r15d
pushq $0x4
popq %r13
cmpl %r12d, %r13d
jae 0x22b46
movl %r13d, %eax
imulq %rbx, %rax
movq 0x8(%rsp), %rcx
leaq (%rcx,%rax,8), %rdx
movq %r14, %rdi
movq %r14, %rsi
movq %rbx, %rcx
movl %r15d, %r8d
callq 0x298b0
addq %rax, (%r14,%rbx,8)
addl $0x2, %r13d
addl %ebp, %r15d
jmp 0x22b13
movl %r12d, 0x14(%rsp)
movq 0x8(%rsp), %rax
leaq (%rax,%rbx,8), %rsi
movq 0x68(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rdx
movl 0x60(%rsp), %r12d
movl %r12d, %ecx
callq 0x181a0
movq %rax, (%r15,%rbx,8)
leal (%r12,%r12,2), %r15d
pushq $0x3
popq %r13
movl 0x14(%rsp), %ecx
cmpl %ecx, %r13d
jae 0x22bba
movl %r13d, %eax
imulq %rbx, %rax
movq 0x8(%rsp), %rcx
leaq (%rcx,%rax,8), %rdx
movq %r14, %r12
movq 0x68(%rsp), %r14
movq %r14, %rdi
movq %r14, %rsi
movq %rbx, %rcx
movl %r15d, %r8d
callq 0x298b0
addq %rax, (%r14,%rbx,8)
movq %r12, %r14
addl $0x2, %r13d
addl %ebp, %r15d
jmp 0x22b78
movl %ecx, %eax
imulq %rbx, %rax
movl 0x60(%rsp), %r8d
imull %ecx, %r8d
movq 0x8(%rsp), %rdx
leaq (%rdx,%rax,8), %rdx
testb $0x1, %cl
jne 0x22c05
movq %r14, %rdi
movq %r14, %rsi
movq 0x18(%rsp), %r15
movq %r15, %rcx
callq 0x298b0
leaq (%r14,%r15,8), %rcx
addq %rax, (%rcx)
jae 0x22bfe
addq $0x1, 0x8(%rcx)
leaq 0x8(%rcx), %rcx
jb 0x22bf3
movq 0x68(%rsp), %r15
jmp 0x22c31
movq 0x68(%rsp), %r15
movq %r15, %rdi
movq %r15, %rsi
movq 0x18(%rsp), %r12
movq %r12, %rcx
callq 0x298b0
leaq (%r15,%r12,8), %rcx
addq %rax, (%rcx)
jae 0x22c31
addq $0x1, 0x8(%rcx)
leaq 0x8(%rcx), %rcx
jb 0x22c26
incq %rbx
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x1ac5c
movl %eax, %ebp
testl %eax, %eax
js 0x22c55
movq 0x20(%rsp), %rdi
movq %r14, %rsi
movq %r15, %rdx
jmp 0x22c60
movq 0x20(%rsp), %rdi
movq %r15, %rsi
movq %r14, %rdx
movq %rbx, %rcx
callq 0x17ed0
sarl $0x1f, %ebp
movq %r14, %rdi
movq %r14, %rsi
movq %r15, %rdx
movq %rbx, %rcx
callq 0x17cf0
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nopl (%rax)