// File: marxn[P]pupp/3rdparty/gmp/./mini-gmp/mini-gmp.c
// Function: mpz_gcdext
void
mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v)
{
  mpz_t tu, tv, s0, s1, t0, t1;
  mp_bitcnt_t uz, vz, gz;
  mp_bitcnt_t power;

  if (u->_mp_size == 0)
    {
      /* g = 0 u + sgn(v) v */
      signed long sign = mpz_sgn (v);
      mpz_abs (g, v);
      if (s)
	mpz_set_ui (s, 0);
      if (t)
	mpz_set_si (t, sign);
      return;
    }

  if (v->_mp_size == 0)
    {
      /* g = sgn(u) u + 0 v */
      signed long sign = mpz_sgn (u);
      mpz_abs (g, u);
      if (s)
	mpz_set_si (s, sign);
      if (t)
	mpz_set_ui (t, 0);
      return;
    }

  mpz_init (tu);
  mpz_init (tv);
  mpz_init (s0);
  mpz_init (s1);
  mpz_init (t0);
  mpz_init (t1);

  mpz_abs (tu, u);
  uz = mpz_make_odd (tu);
  mpz_abs (tv, v);
  vz = mpz_make_odd (tv);
  gz = GMP_MIN (uz, vz);

  uz -= gz;
  vz -= gz;

  /* Cofactors corresponding to odd gcd. gz handled later. */
  if (tu->_mp_size < tv->_mp_size)
    {
      mpz_swap (tu, tv);
      MPZ_SRCPTR_SWAP (u, v);
      MPZ_PTR_SWAP (s, t);
      MP_BITCNT_T_SWAP (uz, vz);
    }

  /* Maintain
   *
   * u = t0 tu + t1 tv
   * v = s0 tu + s1 tv
   *
   * where u and v denote the inputs with common factors of two
   * eliminated, and det (s0, t0; s1, t1) = 2^p. Then
   *
   * 2^p tu =  s1 u - t1 v
   * 2^p tv = -s0 u + t0 v
   */

  /* After initial division, tu = q tv + tu', we have
   *
   * u = 2^uz (tu' + q tv)
   * v = 2^vz tv
   *
   * or
   *
   * t0 = 2^uz, t1 = 2^uz q
   * s0 = 0,    s1 = 2^vz
   */

  mpz_setbit (t0, uz);
  mpz_tdiv_qr (t1, tu, tu, tv);
  mpz_mul_2exp (t1, t1, uz);

  mpz_setbit (s1, vz);
  power = uz + vz;

  if (tu->_mp_size > 0)
    {
      mp_bitcnt_t shift;
      shift = mpz_make_odd (tu);
      mpz_mul_2exp (t0, t0, shift);
      mpz_mul_2exp (s0, s0, shift);
      power += shift;

      for (;;)
	{
	  int c;
	  c = mpz_cmp (tu, tv);
	  if (c == 0)
	    break;

	  if (c < 0)
	    {
	      /* tv = tv' + tu
	       *
	       * u = t0 tu + t1 (tv' + tu) = (t0 + t1) tu + t1 tv'
	       * v = s0 tu + s1 (tv' + tu) = (s0 + s1) tu + s1 tv' */

	      mpz_sub (tv, tv, tu);
	      mpz_add (t0, t0, t1);
	      mpz_add (s0, s0, s1);

	      shift = mpz_make_odd (tv);
	      mpz_mul_2exp (t1, t1, shift);
	      mpz_mul_2exp (s1, s1, shift);
	    }
	  else
	    {
	      mpz_sub (tu, tu, tv);
	      mpz_add (t1, t0, t1);
	      mpz_add (s1, s0, s1);

	      shift = mpz_make_odd (tu);
	      mpz_mul_2exp (t0, t0, shift);
	      mpz_mul_2exp (s0, s0, shift);
	    }
	  power += shift;
	}
    }

  /* Now tv = odd part of gcd, and -s0 and t0 are corresponding
     cofactors. */

  mpz_mul_2exp (tv, tv, gz);
  mpz_neg (s0, s0);

  /* 2^p g = s0 u + t0 v. Eliminate one factor of two at a time. To
     adjust cofactors, we need u / g and v / g */

  mpz_divexact (s1, v, tv);
  mpz_abs (s1, s1);
  mpz_divexact (t1, u, tv);
  mpz_abs (t1, t1);

  while (power-- > 0)
    {
      /* s0 u + t0 v = (s0 - v/g) u - (t0 + u/g) v */
      if (mpz_odd_p (s0) || mpz_odd_p (t0))
	{
	  mpz_sub (s0, s0, s1);
	  mpz_add (t0, t0, t1);
	}
      mpz_divexact_ui (s0, s0, 2);
      mpz_divexact_ui (t0, t0, 2);
    }

  /* Arrange so that |s| < |u| / 2g */
  mpz_add (s1, s0, s1);
  if (mpz_cmpabs (s0, s1) > 0)
    {
      mpz_swap (s0, s1);
      mpz_sub (t0, t0, t1);
    }
  if (u->_mp_size < 0)
    mpz_neg (s0, s0);
  if (v->_mp_size < 0)
    mpz_neg (t0, t0);

  mpz_swap (g, tv);
  if (s)
    mpz_swap (s, s0);
  if (t)
    mpz_swap (t, t0);

  mpz_clear (tu);
  mpz_clear (tv);
  mpz_clear (s0);
  mpz_clear (s1);
  mpz_clear (t0);
  mpz_clear (t1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x0, 0x4(%rax)
jne 0x6e88
movq -0x28(%rbp), %rdi
callq 0x4030
cltq
movq %rax, -0xb8(%rbp)
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x43f0
cmpq $0x0, -0x10(%rbp)
je 0x6e6c
movq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x3350
cmpq $0x0, -0x18(%rbp)
je 0x6e83
movq -0x18(%rbp), %rdi
movq -0xb8(%rbp), %rsi
callq 0x32f0
jmp 0x7413
movq -0x28(%rbp), %rax
cmpl $0x0, 0x4(%rax)
jne 0x6ee1
movq -0x20(%rbp), %rdi
callq 0x4030
cltq
movq %rax, -0xc0(%rbp)
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x43f0
cmpq $0x0, -0x10(%rbp)
je 0x6ec8
movq -0x10(%rbp), %rdi
movq -0xc0(%rbp), %rsi
callq 0x32f0
cmpq $0x0, -0x18(%rbp)
je 0x6edc
movq -0x18(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x3350
jmp 0x7413
leaq -0x40(%rbp), %rdi
callq 0x31e0
leaq -0x50(%rbp), %rdi
callq 0x31e0
leaq -0x60(%rbp), %rdi
callq 0x31e0
leaq -0x70(%rbp), %rdi
callq 0x31e0
leaq -0x80(%rbp), %rdi
callq 0x31e0
leaq -0x90(%rbp), %rdi
callq 0x31e0
leaq -0x40(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x43f0
leaq -0x40(%rbp), %rdi
callq 0x6d90
movq %rax, -0x98(%rbp)
leaq -0x50(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x43f0
leaq -0x50(%rbp), %rdi
callq 0x6d90
movq %rax, -0xa0(%rbp)
movq -0x98(%rbp), %rax
cmpq -0xa0(%rbp), %rax
jae 0x6f74
movq -0x98(%rbp), %rax
movq %rax, -0xf0(%rbp)
jmp 0x6f82
movq -0xa0(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0xf0(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rcx
movq -0x98(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x98(%rbp)
movq -0xa8(%rbp), %rcx
movq -0xa0(%rbp), %rax
subq %rcx, %rax
movq %rax, -0xa0(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x4c(%rbp), %eax
jge 0x7041
leaq -0x40(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x4480
movq -0x20(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0xc8(%rbp), %rax
movq %rax, -0x28(%rbp)
jmp 0x6ff5
movq -0x10(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0xd0(%rbp), %rax
movq %rax, -0x18(%rbp)
jmp 0x7015
movq -0x98(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0xa0(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0xd8(%rbp), %rax
movq %rax, -0xa0(%rbp)
jmp 0x7041
leaq -0x80(%rbp), %rdi
movq -0x98(%rbp), %rsi
callq 0x7420
leaq -0x90(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq -0x40(%rbp), %rdx
leaq -0x50(%rbp), %rcx
callq 0x5700
leaq -0x90(%rbp), %rdi
leaq -0x90(%rbp), %rsi
movq -0x98(%rbp), %rdx
callq 0x5000
leaq -0x70(%rbp), %rdi
movq -0xa0(%rbp), %rsi
callq 0x7420
movq -0x98(%rbp), %rax
addq -0xa0(%rbp), %rax
movq %rax, -0xb0(%rbp)
cmpl $0x0, -0x3c(%rbp)
jle 0x722c
leaq -0x40(%rbp), %rdi
callq 0x6d90
movq %rax, -0xe0(%rbp)
leaq -0x80(%rbp), %rdi
leaq -0x80(%rbp), %rsi
movq -0xe0(%rbp), %rdx
callq 0x5000
leaq -0x60(%rbp), %rdi
leaq -0x60(%rbp), %rsi
movq -0xe0(%rbp), %rdx
callq 0x5000
movq -0xe0(%rbp), %rax
addq -0xb0(%rbp), %rax
movq %rax, -0xb0(%rbp)
leaq -0x40(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x41b0
movl %eax, -0xe4(%rbp)
cmpl $0x0, -0xe4(%rbp)
jne 0x7120
jmp 0x722a
cmpl $0x0, -0xe4(%rbp)
jge 0x719f
leaq -0x50(%rbp), %rdi
leaq -0x50(%rbp), %rsi
leaq -0x40(%rbp), %rdx
callq 0x4c50
leaq -0x80(%rbp), %rdi
leaq -0x80(%rbp), %rsi
leaq -0x90(%rbp), %rdx
callq 0x48a0
leaq -0x60(%rbp), %rdi
leaq -0x60(%rbp), %rsi
leaq -0x70(%rbp), %rdx
callq 0x48a0
leaq -0x50(%rbp), %rdi
callq 0x6d90
movq %rax, -0xe0(%rbp)
leaq -0x90(%rbp), %rdi
leaq -0x90(%rbp), %rsi
movq -0xe0(%rbp), %rdx
callq 0x5000
leaq -0x70(%rbp), %rdi
leaq -0x70(%rbp), %rsi
movq -0xe0(%rbp), %rdx
callq 0x5000
jmp 0x7210
leaq -0x40(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq -0x50(%rbp), %rdx
callq 0x4c50
leaq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rsi
leaq -0x90(%rbp), %rdx
callq 0x48a0
leaq -0x70(%rbp), %rdi
leaq -0x60(%rbp), %rsi
leaq -0x70(%rbp), %rdx
callq 0x48a0
leaq -0x40(%rbp), %rdi
callq 0x6d90
movq %rax, -0xe0(%rbp)
leaq -0x80(%rbp), %rdi
leaq -0x80(%rbp), %rsi
movq -0xe0(%rbp), %rdx
callq 0x5000
leaq -0x60(%rbp), %rdi
leaq -0x60(%rbp), %rsi
movq -0xe0(%rbp), %rdx
callq 0x5000
movq -0xe0(%rbp), %rax
addq -0xb0(%rbp), %rax
movq %rax, -0xb0(%rbp)
jmp 0x70ff
jmp 0x722c
leaq -0x50(%rbp), %rdi
leaq -0x50(%rbp), %rsi
movq -0xa8(%rbp), %rdx
callq 0x5000
leaq -0x60(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x4440
leaq -0x70(%rbp), %rdi
movq -0x28(%rbp), %rsi
leaq -0x50(%rbp), %rdx
callq 0x5ff0
leaq -0x70(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x43f0
leaq -0x90(%rbp), %rdi
movq -0x20(%rbp), %rsi
leaq -0x50(%rbp), %rdx
callq 0x5ff0
leaq -0x90(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x43f0
movq -0xb0(%rbp), %rax
movq %rax, %rcx
addq $-0x1, %rcx
movq %rcx, -0xb0(%rbp)
cmpq $0x0, %rax
jbe 0x7333
cmpl $0x0, -0x5c(%rbp)
setne %al
andb $0x1, %al
movzbl %al, %eax
movq -0x58(%rbp), %rcx
movq (%rcx), %rcx
andl %ecx, %eax
cmpl $0x0, %eax
jne 0x72e5
cmpl $0x0, -0x7c(%rbp)
setne %al
andb $0x1, %al
movzbl %al, %eax
movq -0x78(%rbp), %rcx
movq (%rcx), %rcx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x730a
leaq -0x60(%rbp), %rdi
leaq -0x60(%rbp), %rsi
leaq -0x70(%rbp), %rdx
callq 0x4c50
leaq -0x80(%rbp), %rdi
leaq -0x80(%rbp), %rsi
leaq -0x90(%rbp), %rdx
callq 0x48a0
leaq -0x60(%rbp), %rdi
leaq -0x60(%rbp), %rsi
movl $0x2, %edx
callq 0x66e0
leaq -0x80(%rbp), %rdi
leaq -0x80(%rbp), %rsi
movl $0x2, %edx
callq 0x66e0
jmp 0x7292
leaq -0x70(%rbp), %rdi
leaq -0x60(%rbp), %rsi
leaq -0x70(%rbp), %rdx
callq 0x48a0
leaq -0x60(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x42f0
cmpl $0x0, %eax
jle 0x7377
leaq -0x60(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x4480
leaq -0x80(%rbp), %rdi
leaq -0x80(%rbp), %rsi
leaq -0x90(%rbp), %rdx
callq 0x4c50
movq -0x20(%rbp), %rax
cmpl $0x0, 0x4(%rax)
jge 0x738e
leaq -0x60(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x4440
movq -0x28(%rbp), %rax
cmpl $0x0, 0x4(%rax)
jge 0x73a5
leaq -0x80(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x4440
movq -0x8(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x4480
cmpq $0x0, -0x10(%rbp)
je 0x73c6
movq -0x10(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x4480
cmpq $0x0, -0x18(%rbp)
je 0x73da
movq -0x18(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x4480
leaq -0x40(%rbp), %rdi
callq 0x32c0
leaq -0x50(%rbp), %rdi
callq 0x32c0
leaq -0x60(%rbp), %rdi
callq 0x32c0
leaq -0x70(%rbp), %rdi
callq 0x32c0
leaq -0x80(%rbp), %rdi
callq 0x32c0
leaq -0x90(%rbp), %rdi
callq 0x32c0
addq $0xf0, %rsp
popq %rbp
retq
nopl (%rax)