// File: /workspace/github_cpp_makefile_star2_O3/marxn[P]pupp/3rdparty/gmp/mpn/toom_interpolate_7pts.c
// Function: _gmpn_toom_interpolate_7pts
void
mpn_toom_interpolate_7pts (mp_ptr rp, mp_size_t n, enum toom7_flags flags,
			   mp_ptr w1, mp_ptr w3, mp_ptr w4, mp_ptr w5,
			   mp_size_t w6n, mp_ptr tp)
{
  mp_size_t m;
  mp_limb_t cy;

  m = 2*n + 1;
#define w0 rp
#define w2 (rp + 2*n)
#define w6 (rp + 6*n)

  ASSERT (w6n > 0);
  ASSERT (w6n <= 2*n);

  /* Using formulas similar to Marco Bodrato's

     W5 = W5 + W4
     W1 =(W4 - W1)/2
     W4 = W4 - W0
     W4 =(W4 - W1)/4 - W6*16
     W3 =(W2 - W3)/2
     W2 = W2 - W3

     W5 = W5 - W2*65      May be negative.
     W2 = W2 - W6 - W0
     W5 =(W5 + W2*45)/2   Now >= 0 again.
     W4 =(W4 - W2)/3
     W2 = W2 - W4

     W1 = W5 - W1         May be negative.
     W5 =(W5 - W3*8)/9
     W3 = W3 - W5
     W1 =(W1/15 + W5)/2   Now >= 0 again.
     W5 = W5 - W1

     where W0 = f(0), W1 = f(-2), W2 = f(1), W3 = f(-1),
	   W4 = f(2), W5 = f(1/2), W6 = f(oo),

     Note that most intermediate results are positive; the ones that
     may be negative are represented in two's complement. We must
     never shift right a value that may be negative, since that would
     invalidate the sign bit. On the other hand, divexact by odd
     numbers work fine with two's complement.
  */

  mpn_add_n (w5, w5, w4, m);
  if (flags & toom7_w1_neg)
    {
#ifdef HAVE_NATIVE_mpn_rsh1add_n
      mpn_rsh1add_n (w1, w1, w4, m);
#else
      mpn_add_n (w1, w1, w4, m);  ASSERT (!(w1[0] & 1));
      mpn_rshift (w1, w1, m, 1);
#endif
    }
  else
    {
#ifdef HAVE_NATIVE_mpn_rsh1sub_n
      mpn_rsh1sub_n (w1, w4, w1, m);
#else
      mpn_sub_n (w1, w4, w1, m);  ASSERT (!(w1[0] & 1));
      mpn_rshift (w1, w1, m, 1);
#endif
    }
  mpn_sub (w4, w4, m, w0, 2*n);
  mpn_sub_n (w4, w4, w1, m);  ASSERT (!(w4[0] & 3));
  mpn_rshift (w4, w4, m, 2); /* w4>=0 */

  tp[w6n] = mpn_lshift (tp, w6, w6n, 4);
  mpn_sub (w4, w4, m, tp, w6n+1);

  if (flags & toom7_w3_neg)
    {
#ifdef HAVE_NATIVE_mpn_rsh1add_n
      mpn_rsh1add_n (w3, w3, w2, m);
#else
      mpn_add_n (w3, w3, w2, m);  ASSERT (!(w3[0] & 1));
      mpn_rshift (w3, w3, m, 1);
#endif
    }
  else
    {
#ifdef HAVE_NATIVE_mpn_rsh1sub_n
      mpn_rsh1sub_n (w3, w2, w3, m);
#else
      mpn_sub_n (w3, w2, w3, m);  ASSERT (!(w3[0] & 1));
      mpn_rshift (w3, w3, m, 1);
#endif
    }

  mpn_sub_n (w2, w2, w3, m);

  mpn_submul_1 (w5, w2, m, 65);
  mpn_sub (w2, w2, m, w6, w6n);
  mpn_sub (w2, w2, m, w0, 2*n);

  mpn_addmul_1 (w5, w2, m, 45);  ASSERT (!(w5[0] & 1));
  mpn_rshift (w5, w5, m, 1);
  mpn_sub_n (w4, w4, w2, m);

  mpn_divexact_by3 (w4, w4, m);
  mpn_sub_n (w2, w2, w4, m);

  mpn_sub_n (w1, w5, w1, m);
  mpn_lshift (tp, w3, m, 3);
  mpn_sub_n (w5, w5, tp, m);
  mpn_divexact_by9 (w5, w5, m);
  mpn_sub_n (w3, w3, w5, m);

  mpn_divexact_by15 (w1, w1, m);
  mpn_add_n (w1, w1, w5, m);  ASSERT (!(w1[0] & 1));
  mpn_rshift (w1, w1, m, 1); /* w1>=0 now */
  mpn_sub_n (w5, w5, w1, m);

  /* These bounds are valid for the 4x4 polynomial product of toom44,
   * and they are conservative for toom53 and toom62. */
  ASSERT (w1[2*n] < 2);
  ASSERT (w2[2*n] < 3);
  ASSERT (w3[2*n] < 4);
  ASSERT (w4[2*n] < 3);
  ASSERT (w5[2*n] < 2);

  /* Addition chain. Note carries and the 2n'th limbs that need to be
   * added in.
   *
   * Special care is needed for w2[2n] and the corresponding carry,
   * since the "simple" way of adding it all together would overwrite
   * the limb at wp[2*n] and rp[4*n] (same location) with the sum of
   * the high half of w3 and the low half of w4.
   *
   *         7    6    5    4    3    2    1    0
   *    |    |    |    |    |    |    |    |    |
   *                  ||w3 (2n+1)|
   *             ||w4 (2n+1)|
   *        ||w5 (2n+1)|        ||w1 (2n+1)|
   *  + | w6 (w6n)|        ||w2 (2n+1)| w0 (2n) |  (share storage with r)
   *  -----------------------------------------------
   *  r |    |    |    |    |    |    |    |    |
   *        c7   c6   c5   c4   c3                 Carries to propagate
   */

  cy = mpn_add_n (rp + n, rp + n, w1, m);
  MPN_INCR_U (w2 + n + 1, n , cy);
  cy = mpn_add_n (rp + 3*n, rp + 3*n, w3, n);
  MPN_INCR_U (w3 + n, n + 1, w2[2*n] + cy);
  cy = mpn_add_n (rp + 4*n, w3 + n, w4, n);
  MPN_INCR_U (w4 + n, n + 1, w3[2*n] + cy);
  cy = mpn_add_n (rp + 5*n, w4 + n, w5, n);
  MPN_INCR_U (w5 + n, n + 1, w4[2*n] + cy);
  if (w6n > n + 1)
    {
      cy = mpn_add_n (rp + 6*n, rp + 6*n, w5 + n, n + 1);
      MPN_INCR_U (rp + 7*n + 1, w6n - n - 1, cy);
    }
  else
    {
      ASSERT_NOCARRY (mpn_add_n (rp + 6*n, rp + 6*n, w5 + n, w6n));
#if WANT_ASSERT
      {
	mp_size_t i;
	for (i = w6n; i <= n; i++)
	  ASSERT (w5[n + i] == 0);
      }
#endif
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %r9, %r12
movq %r8, 0x38(%rsp)
movq %rcx, %r13
movl %edx, %r15d
movq %rsi, %r14
movq %rdi, %rbx
movq 0xb0(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0xa8(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0xa0(%rsp), %rdi
leaq 0x1(%rsi,%rsi), %rbp
movq %rdi, 0x40(%rsp)
movq %rdi, %rsi
movq %r9, %rdx
movq %rbp, %rcx
callq 0x1ba80
movl %r15d, 0x34(%rsp)
movq %r13, %rdi
testb $0x1, %r15b
jne 0x28726
movq %r12, %rsi
movq %r13, %rdx
movq %rbp, %rcx
callq 0x2f670
jmp 0x28734
movq %r13, %rsi
movq %r12, %rdx
movq %rbp, %rcx
callq 0x2f530
leaq (%r14,%r14), %rax
movq %rax, 0x8(%rsp)
testq %r14, %r14
movq 0x38(%rsp), %r15
je 0x2877c
movq %r12, %rdi
movq %r12, %rsi
movq %rbx, %rdx
movq 0x8(%rsp), %rcx
callq 0x1bca0
testq %rax, %rax
je 0x2877c
movq %r14, %rax
shlq $0x4, %rax
addq %r12, %rax
xorl %ecx, %ecx
cmpq $0x1, %rcx
je 0x2877c
subq $0x1, (%rax,%rcx,8)
leaq 0x1(%rcx), %rcx
jb 0x2876b
movq %r12, %rdi
movq %r12, %rsi
movq %r13, 0x60(%rsp)
movq %r13, %rdx
movq %rbp, %rcx
callq 0x1bca0
movq %r12, %rdi
movq %r12, %rsi
movq %rbp, %rdx
movl $0x2, %ecx
callq 0x300c0
movq %r14, 0x20(%rsp)
leaq (%r14,%r14,2), %rsi
movq %rsi, 0x58(%rsp)
shlq $0x4, %rsi
movq %rbx, 0x10(%rsp)
addq %rbx, %rsi
movq 0x28(%rsp), %rbx
movq %rbx, %rdi
movq %rsi, 0x18(%rsp)
movq 0x48(%rsp), %r14
movq %r14, %rdx
movl $0x4, %ecx
callq 0x1bf80
movq %rax, (%rbx,%r14,8)
movq %r14, %rbx
incq %rbx
movq 0x8(%rsp), %rcx
je 0x2881c
movq %r12, %rdi
movq %r12, %rsi
movq 0x28(%rsp), %rdx
movq %rbx, %rcx
callq 0x1bca0
movq 0x8(%rsp), %rcx
testq %rax, %rax
je 0x2881c
cmpq %rcx, %rbx
jg 0x2881c
subq $0x1, (%r12,%rbx,8)
leaq 0x1(%rbx), %rbx
jb 0x2880c
movq 0x10(%rsp), %rax
leaq (%rax,%rcx,8), %r13
testb $0x2, 0x34(%rsp)
jne 0x2883f
movq %r15, %rdi
movq %r13, %rsi
movq %r15, %rdx
movq %rbp, %rcx
callq 0x2f670
jmp 0x28850
movq %r15, %rdi
movq %r15, %rsi
movq %r13, %rdx
movq %rbp, %rcx
callq 0x2f530
movq %r13, %rdi
movq %r13, %rsi
movq %r15, %rdx
movq %rbp, %rcx
callq 0x1bca0
movl $0x41, %ecx
movq 0x40(%rsp), %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0x2ffb0
testq %r14, %r14
je 0x288ac
movq %r13, %rdi
movq %r13, %rsi
movq 0x18(%rsp), %rdx
movq %r14, %rcx
callq 0x1bca0
movq 0x8(%rsp), %rcx
testq %rax, %rax
je 0x288ac
movq %r14, %rax
cmpq %rcx, %rax
jg 0x288ac
subq $0x1, (%r13,%rax,8)
leaq 0x1(%rax), %rax
jb 0x2889b
movq %r15, %r14
cmpq $0x0, 0x20(%rsp)
je 0x288f2
movq %r13, %rdi
movq %r13, %rsi
movq 0x10(%rsp), %rdx
movq 0x8(%rsp), %rcx
callq 0x1bca0
testq %rax, %rax
je 0x288f2
movq 0x20(%rsp), %rax
shlq $0x5, %rax
addq 0x10(%rsp), %rax
xorl %ecx, %ecx
cmpq $0x1, %rcx
je 0x288f2
subq $0x1, (%rax,%rcx,8)
leaq 0x1(%rcx), %rcx
jb 0x288e1
movl $0x2d, %ecx
movq 0x40(%rsp), %r15
movq %r15, %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0x2fea0
movq %r15, %rdi
movq %r15, %rsi
movq %rbp, %rdx
movl $0x1, %ecx
callq 0x300c0
movq %r12, %rdi
movq %r12, %rsi
movq %r13, %rdx
movq %rbp, %rcx
callq 0x1bca0
movabsq $0x5555555555555555, %rcx # imm = 0x5555555555555555
movq %r12, %rdi
movq %r12, %rsi
movq %r12, 0x50(%rsp)
movq %rbp, %rdx
xorl %r8d, %r8d
callq 0x2f070
movq %r13, %rdi
movq %r13, %rsi
movq %r12, %rdx
movq %rbp, %rcx
callq 0x1bca0
movq 0x60(%rsp), %r12
movq %r12, %rdi
movq %r15, %rsi
movq %r12, %rdx
movq %rbp, %rcx
callq 0x1bca0
movq 0x28(%rsp), %rbx
movq %rbx, %rdi
movq %r14, %rsi
movq %rbp, %rdx
movl $0x3, %ecx
callq 0x1bf80
movq %r15, %rdi
movq %r15, %rsi
movq %rbx, %rdx
movq %rbp, %rcx
callq 0x1bca0
movabsq $-0x71c71c71c71c71c7, %r8 # imm = 0x8E38E38E38E38E39
movl $0x9, %ecx
movq %r15, %rdi
movq %r15, %rsi
movq %rbp, %rdx
xorl %r9d, %r9d
callq 0x2efe8
movq %r14, %rdi
movq %r14, %rsi
movq %r15, %rdx
movq %rbp, %rcx
callq 0x1bca0
movabsq $0x1111111111111111, %rcx # imm = 0x1111111111111111
movq %r12, %rdi
movq %r12, %rsi
movq %rbp, %rdx
xorl %r8d, %r8d
callq 0x2f070
movq %r12, %rdi
movq %r12, %rsi
movq %r15, %rdx
movq %rbp, %rcx
callq 0x1ba80
movq %r12, %rdi
movq %r12, %rsi
movq %rbp, %rdx
movl $0x1, %ecx
callq 0x300c0
movq %r15, %rdi
movq %r15, %rsi
movq %r12, %rdx
movq %rbp, %rcx
callq 0x1bca0
movq 0x10(%rsp), %rbx
movq 0x20(%rsp), %r14
leaq (%rbx,%r14,8), %rdi
movq %rdi, %rsi
movq %r12, %rdx
movq %rbp, %rcx
callq 0x1ba80
leaq 0x8(,%r14,8), %rcx
addq %r13, %rcx
addq %rax, (%rcx)
jae 0x28a56
addq $0x1, 0x8(%rcx)
leaq 0x8(%rcx), %rcx
jb 0x28a4b
movq 0x58(%rsp), %rax
leaq (%rbx,%rax,8), %rdi
movq %rdi, %rsi
movq 0x38(%rsp), %r12
movq %r12, %rdx
movq %r14, %rcx
callq 0x1ba80
movq 0x8(%rsp), %rbp
addq (%r13,%rbp,8), %rax
leaq (%r12,%r14,8), %rsi
movq %r12, %r13
movq %rsi, %rcx
addq %rax, (%rcx)
jae 0x28a96
addq $0x1, 0x8(%rcx)
leaq 0x8(%rcx), %rcx
jb 0x28a8b
movq %r14, %rdi
shlq $0x5, %rdi
addq %rbx, %rdi
movq 0x50(%rsp), %r12
movq %r12, %rdx
movq %r14, %rcx
callq 0x1ba80
addq (%r13,%rbp,8), %rax
leaq (%r12,%r14,8), %rsi
movq %rsi, %rcx
addq %rax, (%rcx)
jae 0x28acc
addq $0x1, 0x8(%rcx)
leaq 0x8(%rcx), %rcx
jb 0x28ac1
leaq (%r14,%r14,4), %rax
leaq (%rbx,%rax,8), %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x1ba80
addq (%r12,%rbp,8), %rax
leaq (%r15,%r14,8), %rdx
movq %rdx, %rcx
addq %rax, (%rcx)
jae 0x28afa
addq $0x1, 0x8(%rcx)
leaq 0x8(%rcx), %rcx
jb 0x28aef
leaq 0x1(%r14), %rcx
movq 0x48(%rsp), %rax
cmpq %rax, %rcx
jge 0x28b3f
movq 0x18(%rsp), %rdi
movq %rdi, %rsi
callq 0x1ba80
imulq $0x38, %r14, %rcx
addq %rbx, %rcx
addq $0x8, %rcx
addq %rax, (%rcx)
jae 0x28b30
addq $0x1, 0x8(%rcx)
leaq 0x8(%rcx), %rcx
jb 0x28b25
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x18(%rsp), %rdi
movq %rdi, %rsi
movq %rax, %rcx
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1ba80
nopl (%rax)