// File: /workspace/github_cpp_makefile_star2_O1/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), %eax
movq %r8, %rdx
shlq $0x4, %rdx
addq %rcx, %rdx
leal (%rax,%rax), %ebp
movq %rcx, 0x8(%rsp)
movq %rcx, %rsi
movq %r8, %rcx
movl %ebp, %r8d
callq 0x2fcb0
movq %rax, (%r14,%rbx,8)
cmpl $0x5, %r12d
jb 0x28046
movl 0x60(%rsp), %eax
leal (,%rax,4), %r15d
movl $0x4, %r13d
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 0x2fcb0
addq %rax, (%r14,%rbx,8)
addl $0x2, %r13d
addl %ebp, %r15d
cmpl %r12d, %r13d
jb 0x28015
movq %r14, 0x10(%rsp)
movq 0x8(%rsp), %rax
leaq (%rax,%rbx,8), %rsi
movl %r12d, %r15d
movq 0x68(%rsp), %r12
movq %r12, %rdi
movq %rbx, %rdx
movl 0x60(%rsp), %ecx
callq 0x1c4a0
movl %r15d, %esi
movq %rax, (%r12,%rbx,8)
cmpl $0x4, %r15d
jb 0x280c1
movl 0x60(%rsp), %eax
leal (%rax,%rax,2), %r15d
movl $0x3, %r13d
movl %r13d, %eax
imulq %rbx, %rax
movq 0x8(%rsp), %rcx
leaq (%rcx,%rax,8), %rdx
movq %r12, %rdi
movl %ebp, %r14d
movl %esi, %ebp
movq %r12, %rsi
movq %rbx, %rcx
movl %r15d, %r8d
callq 0x2fcb0
movl %ebp, %esi
movl %r14d, %ebp
addq %rax, (%r12,%rbx,8)
addl $0x2, %r13d
addl %r14d, %r15d
cmpl %esi, %r13d
jb 0x28086
movl %esi, %eax
imulq %rbx, %rax
movl 0x60(%rsp), %r8d
imull %esi, %r8d
movq 0x8(%rsp), %rcx
leaq (%rcx,%rax,8), %rdx
testb $0x1, %sil
jne 0x28112
movq 0x10(%rsp), %r14
movq %r14, %rdi
movq %r14, %rsi
movq 0x18(%rsp), %r15
movq %r15, %rcx
callq 0x2fcb0
leaq (%r14,%r15,8), %rcx
addq %rax, (%rcx)
jae 0x2810b
addq $0x1, 0x8(%rcx)
leaq 0x8(%rcx), %rcx
jb 0x28100
movq 0x68(%rsp), %r15
jmp 0x28143
movq 0x68(%rsp), %r15
movq %r15, %rdi
movq %r15, %rsi
movq 0x18(%rsp), %r12
movq %r12, %rcx
callq 0x2fcb0
leaq (%r15,%r12,8), %rcx
addq %rax, (%rcx)
jae 0x2813e
addq $0x1, 0x8(%rcx)
leaq 0x8(%rcx), %rcx
jb 0x28133
movq 0x10(%rsp), %r14
incq %rbx
movq %rbx, %rax
testq %rax, %rax
jle 0x2816d
movq -0x8(%r14,%rax,8), %rcx
movq -0x8(%r15,%rax,8), %rdx
decq %rax
cmpq %rdx, %rcx
je 0x28149
xorl %ebp, %ebp
cmpq %rcx, %rdx
adcl $-0x1, %ebp
orl $0x1, %ebp
jmp 0x2816f
xorl %ebp, %ebp
testl %ebp, %ebp
js 0x28180
movq 0x20(%rsp), %rdi
movq %r14, %rsi
movq %r15, %rdx
jmp 0x2818b
movq 0x20(%rsp), %rdi
movq %r15, %rsi
movq %r14, %rdx
movq %rbx, %rcx
callq 0x1c1c0
sarl $0x1f, %ebp
movq %r14, %rdi
movq %r14, %rsi
movq %r15, %rdx
movq %rbx, %rcx
callq 0x1bfa0
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq