// File: marxn[P]pupp/3rdparty/gmp/./mini-gmp/mini-gmp.c
// Function: mpz_rootrem
void
mpz_rootrem (mpz_t x, mpz_t r, const mpz_t y, unsigned long z)
{
  int sgn;
  mpz_t t, u;

  sgn = y->_mp_size < 0;
  if ((~z & sgn) != 0)
    gmp_die ("mpz_rootrem: Negative argument, with even root.");
  if (z == 0)
    gmp_die ("mpz_rootrem: Zeroth root.");

  if (mpz_cmpabs_ui (y, 1) <= 0) {
    if (x)
      mpz_set (x, y);
    if (r)
      r->_mp_size = 0;
    return;
  }

  mpz_init (u);
  {
    mp_bitcnt_t tb;
    tb = mpz_sizeinbase (y, 2) / z + 1;
    mpz_init2 (t, tb + 1);
    mpz_setbit (t, tb);
  }

  if (z == 2) /* simplify sqrt loop: z-1 == 1 */
    do {
      mpz_swap (u, t);			/* u = x */
      mpz_tdiv_q (t, y, u);		/* t = y/x */
      mpz_add (t, t, u);		/* t = y/x + x */
      mpz_tdiv_q_2exp (t, t, 1);	/* x'= (y/x + x)/2 */
    } while (mpz_cmpabs (t, u) < 0);	/* |x'| < |x| */
  else /* z != 2 */ {
    mpz_t v;

    mpz_init (v);
    if (sgn)
      mpz_neg (t, t);

    do {
      mpz_swap (u, t);			/* u = x */
      mpz_pow_ui (t, u, z - 1);		/* t = x^(z-1) */
      mpz_tdiv_q (t, y, t);		/* t = y/x^(z-1) */
      mpz_mul_ui (v, u, z - 1);		/* v = x*(z-1) */
      mpz_add (t, t, v);		/* t = y/x^(z-1) + x*(z-1) */
      mpz_tdiv_q_ui (t, t, z);		/* x'=(y/x^(z-1) + x*(z-1))/z */
    } while (mpz_cmpabs (t, u) < 0);	/* |x'| < |x| */

    mpz_clear (v);
  }

  if (r) {
    mpz_pow_ui (t, u, z);
    mpz_sub (r, y, t);
  }
  if (x)
    mpz_swap (x, u);
  mpz_clear (u);
  mpz_clear (t);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x18(%rbp), %rax
cmpl $0x0, 0x4(%rax)
setl %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x24(%rbp)
movq -0x20(%rbp), %rax
xorq $-0x1, %rax
movslq -0x24(%rbp), %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x803c
leaq 0x65bc(%rip), %rdi      # 0xe5f3
callq 0x7b50
cmpq $0x0, -0x20(%rbp)
jne 0x804f
leaq 0x65d9(%rip), %rdi      # 0xe623
callq 0x7b50
movq -0x18(%rbp), %rdi
movl $0x1, %esi
callq 0x4250
cmpl $0x0, %eax
jg 0x808d
cmpq $0x0, -0x8(%rbp)
je 0x8076
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x3390
cmpq $0x0, -0x10(%rbp)
je 0x8088
movq -0x10(%rbp), %rax
movl $0x0, 0x4(%rax)
jmp 0x8225
leaq -0x50(%rbp), %rdi
callq 0x31e0
movq -0x18(%rbp), %rdi
movl $0x2, %esi
callq 0x8230
xorl %ecx, %ecx
movl %ecx, %edx
divq -0x20(%rbp)
addq $0x1, %rax
movq %rax, -0x58(%rbp)
leaq -0x40(%rbp), %rdi
movq -0x58(%rbp), %rsi
addq $0x1, %rsi
callq 0x3250
leaq -0x40(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0x7420
cmpq $0x2, -0x20(%rbp)
jne 0x8133
jmp 0x80db
leaq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x4480
leaq -0x40(%rbp), %rdi
movq -0x18(%rbp), %rsi
leaq -0x50(%rbp), %rdx
callq 0x57c0
leaq -0x40(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq -0x50(%rbp), %rdx
callq 0x48a0
leaq -0x40(%rbp), %rdi
leaq -0x40(%rbp), %rsi
movl $0x1, %edx
callq 0x5b80
leaq -0x40(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x42f0
cmpl $0x0, %eax
jl 0x80db
jmp 0x81d6
leaq -0x70(%rbp), %rdi
callq 0x31e0
cmpl $0x0, -0x24(%rbp)
je 0x814f
leaq -0x40(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x4440
jmp 0x8151
leaq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x4480
leaq -0x40(%rbp), %rdi
leaq -0x50(%rbp), %rsi
movq -0x20(%rbp), %rdx
subq $0x1, %rdx
callq 0x7670
leaq -0x40(%rbp), %rdi
movq -0x18(%rbp), %rsi
leaq -0x40(%rbp), %rdx
callq 0x57c0
leaq -0x70(%rbp), %rdi
leaq -0x50(%rbp), %rsi
movq -0x20(%rbp), %rdx
subq $0x1, %rdx
callq 0x4d50
leaq -0x40(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq -0x70(%rbp), %rdx
callq 0x48a0
leaq -0x40(%rbp), %rdi
leaq -0x40(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x6510
leaq -0x40(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x42f0
cmpl $0x0, %eax
jl 0x8151
leaq -0x70(%rbp), %rdi
callq 0x32c0
cmpq $0x0, -0x10(%rbp)
je 0x81ff
leaq -0x40(%rbp), %rdi
leaq -0x50(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x7670
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
leaq -0x40(%rbp), %rdx
callq 0x4c50
cmpq $0x0, -0x8(%rbp)
je 0x8213
movq -0x8(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x4480
leaq -0x50(%rbp), %rdi
callq 0x32c0
leaq -0x40(%rbp), %rdi
callq 0x32c0
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax,%rax)