// File: /workspace/github_cpp_makefile_star2_O2/marxn[P]pupp/3rdparty/gmp/mpn/toom44_mul.c
// Function: _gmpn_toom44_mul
void
mpn_toom44_mul (mp_ptr pp,
		mp_srcptr ap, mp_size_t an,
		mp_srcptr bp, mp_size_t bn,
		mp_ptr scratch)
{
  mp_size_t n, s, t;
  mp_limb_t cy;
  enum toom7_flags flags;

#define a0  ap
#define a1  (ap + n)
#define a2  (ap + 2*n)
#define a3  (ap + 3*n)
#define b0  bp
#define b1  (bp + n)
#define b2  (bp + 2*n)
#define b3  (bp + 3*n)

  ASSERT (an >= bn);

  n = (an + 3) >> 2;

  s = an - 3 * n;
  t = bn - 3 * n;

  ASSERT (0 < s && s <= n);
  ASSERT (0 < t && t <= n);
  ASSERT (s >= t);

  /* NOTE: The multiplications to v2, vm2, vh and vm1 overwrites the
   * following limb, so these must be computed in order, and we need a
   * one limb gap to tp. */
#define v0    pp				/* 2n */
#define v1    (pp + 2 * n)			/* 2n+1 */
#define vinf  (pp + 6 * n)			/* s+t */
#define v2    scratch				/* 2n+1 */
#define vm2   (scratch + 2 * n + 1)		/* 2n+1 */
#define vh    (scratch + 4 * n + 2)		/* 2n+1 */
#define vm1   (scratch + 6 * n + 3)		/* 2n+1 */
#define tp (scratch + 8*n + 5)

  /* apx and bpx must not overlap with v1 */
#define apx   pp				/* n+1 */
#define amx   (pp + n + 1)			/* n+1 */
#define bmx   (pp + 2*n + 2)			/* n+1 */
#define bpx   (pp + 4*n + 2)			/* n+1 */

  /* Total scratch need: 8*n + 5 + scratch for recursive calls. This
     gives roughly 32 n/3 + log term. */

  /* Compute apx = a0 + 2 a1 + 4 a2 + 8 a3 and amx = a0 - 2 a1 + 4 a2 - 8 a3.  */
  flags = (enum toom7_flags) (toom7_w1_neg & mpn_toom_eval_dgr3_pm2 (apx, amx, ap, n, s, tp));

  /* Compute bpx = b0 + 2 b1 + 4 b2 + 8 b3 and bmx = b0 - 2 b1 + 4 b2 - 8 b3.  */
  flags = (enum toom7_flags) (flags ^ (toom7_w1_neg & mpn_toom_eval_dgr3_pm2 (bpx, bmx, bp, n, t, tp)));

  TOOM44_MUL_N_REC (v2, apx, bpx, n + 1, tp);	/* v2,  2n+1 limbs */
  TOOM44_MUL_N_REC (vm2, amx, bmx, n + 1, tp);	/* vm2,  2n+1 limbs */

  /* Compute apx = 8 a0 + 4 a1 + 2 a2 + a3 = (((2*a0 + a1) * 2 + a2) * 2 + a3 */
#if HAVE_NATIVE_mpn_addlsh1_n
  cy = mpn_addlsh1_n (apx, a1, a0, n);
  cy = 2*cy + mpn_addlsh1_n (apx, a2, apx, n);
  if (s < n)
    {
      mp_limb_t cy2;
      cy2 = mpn_addlsh1_n (apx, a3, apx, s);
      apx[n] = 2*cy + mpn_lshift (apx + s, apx + s, n - s, 1);
      MPN_INCR_U (apx + s, n+1-s, cy2);
    }
  else
    apx[n] = 2*cy + mpn_addlsh1_n (apx, a3, apx, n);
#else
  cy = mpn_lshift (apx, a0, n, 1);
  cy += mpn_add_n (apx, apx, a1, n);
  cy = 2*cy + mpn_lshift (apx, apx, n, 1);
  cy += mpn_add_n (apx, apx, a2, n);
  cy = 2*cy + mpn_lshift (apx, apx, n, 1);
  apx[n] = cy + mpn_add (apx, apx, n, a3, s);
#endif

  /* Compute bpx = 8 b0 + 4 b1 + 2 b2 + b3 = (((2*b0 + b1) * 2 + b2) * 2 + b3 */
#if HAVE_NATIVE_mpn_addlsh1_n
  cy = mpn_addlsh1_n (bpx, b1, b0, n);
  cy = 2*cy + mpn_addlsh1_n (bpx, b2, bpx, n);
  if (t < n)
    {
      mp_limb_t cy2;
      cy2 = mpn_addlsh1_n (bpx, b3, bpx, t);
      bpx[n] = 2*cy + mpn_lshift (bpx + t, bpx + t, n - t, 1);
      MPN_INCR_U (bpx + t, n+1-t, cy2);
    }
  else
    bpx[n] = 2*cy + mpn_addlsh1_n (bpx, b3, bpx, n);
#else
  cy = mpn_lshift (bpx, b0, n, 1);
  cy += mpn_add_n (bpx, bpx, b1, n);
  cy = 2*cy + mpn_lshift (bpx, bpx, n, 1);
  cy += mpn_add_n (bpx, bpx, b2, n);
  cy = 2*cy + mpn_lshift (bpx, bpx, n, 1);
  bpx[n] = cy + mpn_add (bpx, bpx, n, b3, t);
#endif

  ASSERT (apx[n] < 15);
  ASSERT (bpx[n] < 15);

  TOOM44_MUL_N_REC (vh, apx, bpx, n + 1, tp);	/* vh,  2n+1 limbs */

  /* Compute apx = a0 + a1 + a2 + a3 and amx = a0 - a1 + a2 - a3.  */
  flags = (enum toom7_flags) (flags | (toom7_w3_neg & mpn_toom_eval_dgr3_pm1 (apx, amx, ap, n, s, tp)));

  /* Compute bpx = b0 + b1 + b2 + b3 and bmx = b0 - b1 + b2 - b3.  */
  flags = (enum toom7_flags) (flags ^ (toom7_w3_neg & mpn_toom_eval_dgr3_pm1 (bpx, bmx, bp, n, t, tp)));

  TOOM44_MUL_N_REC (vm1, amx, bmx, n + 1, tp);	/* vm1,  2n+1 limbs */
  /* Clobbers amx, bmx. */
  TOOM44_MUL_N_REC (v1, apx, bpx, n + 1, tp);	/* v1,  2n+1 limbs */

  TOOM44_MUL_N_REC (v0, a0, b0, n, tp);
  if (s > t)
    mpn_mul (vinf, a3, s, b3, t);
  else
    TOOM44_MUL_N_REC (vinf, a3, b3, s, tp);	/* vinf, s+t limbs */

  mpn_toom_interpolate_7pts (pp, n, flags, vm2, vm1, v2, vh, s + t, tp);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %r9, 0x10(%rsp)
movq %r8, %rbx
movq %rcx, 0x48(%rsp)
movq %rdx, %r8
movq %rsi, %rdx
movq %rdi, %r15
leaq 0x3(%r8), %r14
movq %r14, %r12
sarq $0x2, %r12
leaq (%r12,%r12,2), %rcx
movq %r8, 0x98(%rsp)
subq %rcx, %r8
movq %rbx, 0xa0(%rsp)
movq %rcx, 0x18(%rsp)
subq %rcx, %rbx
leaq (%rdi,%r12,8), %rsi
addq $0x8, %rsi
movq %r12, %rax
shlq $0x6, %rax
leaq (%r9,%rax), %r13
addq $0x28, %r13
movq %rsi, 0x70(%rsp)
movq %rdx, 0x28(%rsp)
movq %r12, %rcx
movq %r8, 0x58(%rsp)
movq %r13, %r9
callq 0x226f4
movl %eax, 0x8c(%rsp)
andq $-0x4, %r14
movq %r14, 0x60(%rsp)
leaq (%r15,%r14,8), %rbp
addq $0x10, %rbp
leaq (%r12,%r12), %rax
movq %rax, 0x78(%rsp)
movq %r12, %r9
shlq $0x4, %r9
leaq (%r15,%r9), %r14
addq $0x10, %r14
movq %rbp, %rdi
movq %r14, %rsi
movq 0x48(%rsp), %rdx
movq %r12, %rcx
movq %rbx, 0x20(%rsp)
movq %rbx, %r8
movq %r9, %rbx
movq %r13, %r9
callq 0x226f4
movl %eax, 0x88(%rsp)
leaq 0x1(%r12), %rdx
movq 0x10(%rsp), %rax
addq %rbx, %rax
addq $0x8, %rax
movq %rax, 0x8(%rsp)
cmpq $0x4f, %r12
movq %r13, 0x38(%rsp)
movq %rdx, 0x68(%rsp)
movq %rbp, 0x40(%rsp)
movq %rbx, 0x30(%rsp)
jle 0x1e904
movq 0x10(%rsp), %rdi
movq %r15, %rsi
movq %rbp, %rcx
movq %rdx, %rbx
movq %rdx, %r8
movq %r13, %r9
callq 0x1d2dc
movq 0x8(%rsp), %rdi
movq 0x70(%rsp), %rsi
movq %rbx, %rdx
movq %r14, %rcx
movq %rbx, %r8
movq %r13, %r9
callq 0x1d2dc
jmp 0x1e938
movq 0x10(%rsp), %rdi
movq %r15, %rsi
movq %rbp, %rcx
movq %rdx, %rbx
movq %rdx, %r8
movq %r13, %r9
callq 0x1c488
movq 0x8(%rsp), %rdi
movq 0x70(%rsp), %rsi
movq %rbx, %rdx
movq %r14, %rcx
movq %rbx, %r8
movq %r13, %r9
callq 0x1c488
movq %r14, 0x90(%rsp)
movq 0x28(%rsp), %rbx
leaq (%rbx,%r12,8), %rsi
movq %r15, %rdi
movq %rbx, %rdx
movq %r12, %rcx
callq 0x291c0
movq %rax, %r14
movq 0x78(%rsp), %rax
leaq (%rbx,%rax,8), %rsi
movq %r15, %rdi
movq %r15, %rdx
movq %r12, %rcx
callq 0x291c0
leaq (%rax,%r14,2), %rbp
movq %r12, %r14
movq 0x58(%rsp), %r13
subq %r13, %r14
jle 0x1e9cc
movq 0x18(%rsp), %rax
leaq (%rbx,%rax,8), %rsi
movq %r15, %rdi
movq %r15, %rdx
movq %r13, %rcx
callq 0x291c0
movq %rax, %rbx
leaq (%r15,%r13,8), %r13
pushq $0x1
popq %rcx
movq %r13, %rdi
movq %r13, %rsi
movq %r14, %rdx
callq 0x181a0
leaq (%rax,%rbp,2), %rax
movq %rax, (%r15,%r12,8)
addq %rbx, (%r13)
jae 0x1e9ca
addq $0x1, 0x8(%r13)
leaq 0x8(%r13), %r13
jb 0x1e9bf
jmp 0x1e9eb
movq 0x18(%rsp), %rax
leaq (%rbx,%rax,8), %rsi
movq %r15, %rdi
movq %r15, %rdx
movq %r12, %rcx
callq 0x291c0
leaq (%rax,%rbp,2), %rax
movq %rax, (%r15,%r12,8)
movq 0x40(%rsp), %rbp
movq 0x48(%rsp), %rbx
leaq (%rbx,%r12,8), %rsi
movq %rbp, %rdi
movq %rbx, %rdx
movq %r12, %rcx
callq 0x291c0
movq %rax, %r14
movq 0x78(%rsp), %rax
leaq (%rbx,%rax,8), %rsi
movq %rbp, %rdi
movq %rbp, %rdx
movq %r12, %rcx
callq 0x291c0
leaq (%rax,%r14,2), %rax
movq %rax, 0x8(%rsp)
movq %r12, %r14
movq 0x20(%rsp), %r13
subq %r13, %r14
jle 0x1ea98
movq 0x18(%rsp), %rax
leaq (%rbx,%rax,8), %rsi
movq %rbp, %rdi
movq %rbp, %rdx
movq %r13, %rcx
callq 0x291c0
movq %rax, %rbx
movq 0x20(%rsp), %rax
leaq (,%rax,8), %r13
addq %rbp, %r13
pushq $0x1
popq %rcx
movq %r13, %rdi
movq %r13, %rsi
movq %r14, %rdx
callq 0x181a0
movq 0x8(%rsp), %rcx
leaq (%rax,%rcx,2), %rax
movq %rax, (%rbp,%r12,8)
addq %rbx, (%r13)
jae 0x1ea91
addq $0x1, 0x8(%r13)
leaq 0x8(%r13), %r13
jb 0x1ea86
movq 0x20(%rsp), %r13
jmp 0x1eabd
movq 0x18(%rsp), %rax
leaq (%rbx,%rax,8), %rsi
movq %rbp, %rdi
movq %rbp, %rdx
movq %r12, %rcx
callq 0x291c0
movq 0x8(%rsp), %rcx
leaq (%rax,%rcx,2), %rax
movq %rax, (%rbp,%r12,8)
movq 0x10(%rsp), %rax
movq 0x38(%rsp), %r14
movq 0x60(%rsp), %rcx
leaq (%rax,%rcx,8), %rdi
addq $0x10, %rdi
cmpq $0x4f, %r12
movq 0x68(%rsp), %rdx
movq %rdi, 0x60(%rsp)
movq %r15, %rsi
movq %rbp, %rcx
movq %rdx, %r8
movq %r14, %r9
jle 0x1eaf7
callq 0x1d2dc
jmp 0x1eafc
callq 0x1c488
movq 0x30(%rsp), %rbx
addq %r15, %rbx
movq %r15, %rdi
movq 0x70(%rsp), %rbp
movq %rbp, %rsi
movq 0x28(%rsp), %rdx
movq %r12, %rcx
movq 0x58(%rsp), %r8
movq %r14, %r9
callq 0x22648
movl %eax, 0x8(%rsp)
movq 0x40(%rsp), %rdi
movq %r15, 0x50(%rsp)
movq 0x90(%rsp), %r15
movq %r15, %rsi
movq 0x48(%rsp), %rdx
movq %r12, %rcx
movq %r13, %r8
movq %r14, %r9
callq 0x22648
movl %eax, 0x84(%rsp)
imulq $0x30, %r12, %rcx
movq 0x10(%rsp), %rax
movq %rcx, 0x30(%rsp)
leaq (%rax,%rcx), %rdi
addq $0x18, %rdi
movq %rbp, %rsi
cmpq $0x4f, %r12
jle 0x1ebd0
movq 0x68(%rsp), %rbp
movq %rbp, %rdx
movq %r15, %rcx
movq %rbp, %r8
movq %r14, %r9
callq 0x1d2dc
movq %rbx, %rdi
movq 0x50(%rsp), %r13
movq %r13, %rsi
movq %rbp, %rdx
movq 0x40(%rsp), %rcx
movq %rbp, %r8
movq %r14, %r9
callq 0x1d2dc
cmpq $0x50, %r12
je 0x1ec04
movq %r13, %rdi
movq 0x28(%rsp), %rsi
movq %r12, %rdx
movq 0x48(%rsp), %rbp
movq %rbp, %rcx
movq %r12, %r8
movq %r14, %r9
callq 0x1d2dc
jmp 0x1ec22
movq 0x68(%rsp), %rbp
movq %rbp, %rdx
movq %r15, %rcx
movq %rbp, %r8
movq %r14, %r9
callq 0x1c488
movq %rbx, %rdi
movq 0x50(%rsp), %r13
movq %r13, %rsi
movq %rbp, %rdx
movq 0x40(%rsp), %rcx
movq %rbp, %r8
movq %r14, %r9
callq 0x1c488
movq %r13, %rdi
movq 0x28(%rsp), %rsi
movq %r12, %rdx
movq 0x48(%rsp), %rbp
movq %rbp, %rcx
movq %r12, %r8
movq %r14, %r9
callq 0x1c488
movq 0x58(%rsp), %rbx
movq 0x98(%rsp), %rax
cmpq 0xa0(%rsp), %rax
movq 0x30(%rsp), %rax
jle 0x1ec70
imulq $0x30, %r12, %r15
leaq (%r15,%r13), %rdi
movq 0x28(%rsp), %rax
movq 0x18(%rsp), %rcx
leaq (%rax,%rcx,8), %rsi
leaq (%rbp,%rcx,8), %rcx
movq %rbx, %rdx
movq 0x20(%rsp), %rbp
movq %rbp, %r8
callq 0x18a58
movq 0x38(%rsp), %r14
jmp 0x1ecc4
leaq (%rax,%r13), %rdi
movq 0x28(%rsp), %rax
movq 0x18(%rsp), %rcx
leaq (%rax,%rcx,8), %rsi
leaq (,%rcx,8), %rcx
addq %rbp, %rcx
movq %rbx, %rdx
movq %rbx, %r8
cmpq $0x50, %rbx
jle 0x1eca8
movq 0x38(%rsp), %r14
movq %r14, %r9
callq 0x1d2dc
jmp 0x1ecb5
movq 0x38(%rsp), %r14
movq %r14, %r9
callq 0x1c488
movq 0x20(%rsp), %rbp
movq 0x30(%rsp), %r15
movq 0x50(%rsp), %r13
movl 0x88(%rsp), %eax
xorl 0x8c(%rsp), %eax
andl $0x1, %eax
movl 0x8(%rsp), %ecx
andl $0x2, %ecx
orl %eax, %ecx
movl 0x84(%rsp), %edx
andl $0x2, %edx
xorl %ecx, %edx
movq 0x10(%rsp), %r9
movq 0x78(%rsp), %rax
leaq (%r9,%rax,8), %rcx
addq $0x8, %rcx
leaq (%r9,%r15), %r8
addq $0x18, %r8
addq %rbp, %rbx
subq $0x8, %rsp
movq %r13, %rdi
movq %r12, %rsi
pushq %r14
pushq %rbx
pushq 0x78(%rsp)
callq 0x23460
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop