// File: marxn[P]pupp/3rdparty/gmp/./mini-gmp/mini-gmp.c
// Function: mpz_probab_prime_p
int
mpz_probab_prime_p (const mpz_t n, int reps)
{
  mpz_t nm1;
  mpz_t q;
  mpz_t y;
  mp_bitcnt_t k;
  int is_prime;
  int j;

  /* Note that we use the absolute value of n only, for compatibility
     with the real GMP. */
  if (mpz_even_p (n))
    return (mpz_cmpabs_ui (n, 2) == 0) ? 2 : 0;

  /* Above test excludes n == 0 */
  assert (n->_mp_size != 0);

  if (mpz_cmpabs_ui (n, 64) < 0)
    return (GMP_PRIME_MASK >> (n->_mp_d[0] >> 1)) & 2;

  if (mpz_gcd_ui (NULL, n, GMP_PRIME_PRODUCT) != 1)
    return 0;

  /* All prime factors are >= 31. */
  if (mpz_cmpabs_ui (n, 31*31) < 0)
    return 2;

  /* Use Miller-Rabin, with a deterministic sequence of bases, a[j] =
     j^2 + j + 41 using Euler's polynomial. We potentially stop early,
     if a[j] >= n - 1. Since n >= 31*31, this can happen only if reps >
     30 (a[30] == 971 > 31*31 == 961). */

  mpz_init (nm1);
  mpz_init (q);
  mpz_init (y);

  /* Find q and k, where q is odd and n = 1 + 2**k * q.  */
  nm1->_mp_size = mpz_abs_sub_ui (nm1, n, 1);
  k = mpz_scan1 (nm1, 0);
  mpz_tdiv_q_2exp (q, nm1, k);

  for (j = 0, is_prime = 1; is_prime & (j < reps); j++)
    {
      mpz_set_ui (y, (unsigned long) j*j+j+41);
      if (mpz_cmp (y, nm1) >= 0)
	{
	  /* Don't try any further bases. This "early" break does not affect
	     the result for any reasonable reps value (<=5000 was tested) */
	  assert (j >= 30);
	  break;
	}
      is_prime = gmp_millerrabin (n, nm1, y, q, k);
    }
  mpz_clear (nm1);
  mpz_clear (q);
  mpz_clear (y);

  return is_prime;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x4(%rax)
setne %al
andb $0x1, %al
movzbl %al, %eax
movq -0x10(%rbp), %rcx
movq 0x8(%rcx), %rcx
movq (%rcx), %rcx
andl %ecx, %eax
cmpl $0x0, %eax
jne 0x88d6
movq -0x10(%rbp), %rdi
movl $0x2, %esi
callq 0x4250
movl %eax, %edx
xorl %eax, %eax
movl $0x2, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0x8a9c
movq -0x10(%rbp), %rax
cmpl $0x0, 0x4(%rax)
je 0x88e2
jmp 0x8901
leaq 0x5de3(%rip), %rdi      # 0xe6cc
leaq 0x57e4(%rip), %rsi      # 0xe0d4
movl $0xd47, %edx            # imm = 0xD47
leaq 0x5de1(%rip), %rcx      # 0xe6dd
callq 0x1070
movq -0x10(%rbp), %rdi
movl $0x40, %esi
callq 0x4250
cmpl $0x0, %eax
jge 0x8936
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rcx
shrq %rcx
movl $0xc96996dc, %eax       # imm = 0xC96996DC
shrq %cl, %rax
andq $0x2, %rax
movl %eax, -0x4(%rbp)
jmp 0x8a9c
movq -0x10(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edi
movl $0xc0cfd797, %edx       # imm = 0xC0CFD797
callq 0x6790
cmpq $0x1, %rax
je 0x895a
movl $0x0, -0x4(%rbp)
jmp 0x8a9c
movq -0x10(%rbp), %rdi
movl $0x3c1, %esi            # imm = 0x3C1
callq 0x4250
cmpl $0x0, %eax
jge 0x8979
movl $0x2, -0x4(%rbp)
jmp 0x8a9c
leaq -0x30(%rbp), %rdi
callq 0x31e0
leaq -0x40(%rbp), %rdi
callq 0x31e0
leaq -0x50(%rbp), %rdi
callq 0x31e0
leaq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl $0x1, %edx
callq 0x4680
movl %eax, -0x2c(%rbp)
leaq -0x30(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x8ab0
movq %rax, -0x58(%rbp)
leaq -0x40(%rbp), %rdi
leaq -0x30(%rbp), %rsi
movq -0x58(%rbp), %rdx
callq 0x5b80
movl $0x0, -0x60(%rbp)
movl $0x1, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
movl -0x60(%rbp), %ecx
cmpl -0x14(%rbp), %ecx
setl %cl
andb $0x1, %cl
movzbl %cl, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x8a7b
leaq -0x50(%rbp), %rdi
movslq -0x60(%rbp), %rsi
movslq -0x60(%rbp), %rax
imulq %rax, %rsi
movslq -0x60(%rbp), %rax
addq %rax, %rsi
addq $0x29, %rsi
callq 0x3350
leaq -0x50(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x41b0
cmpl $0x0, %eax
jl 0x8a51
cmpl $0x1e, -0x60(%rbp)
jl 0x8a30
jmp 0x8a4f
leaq 0x5cd8(%rip), %rdi      # 0xe70f
leaq 0x5696(%rip), %rsi      # 0xe0d4
movl $0xd68, %edx            # imm = 0xD68
leaq 0x5c93(%rip), %rcx      # 0xe6dd
callq 0x1070
jmp 0x8a7b
movq -0x10(%rbp), %rdi
leaq -0x30(%rbp), %rsi
leaq -0x50(%rbp), %rdx
leaq -0x40(%rbp), %rcx
movq -0x58(%rbp), %r8
callq 0x8be0
movl %eax, -0x5c(%rbp)
movl -0x60(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x60(%rbp)
jmp 0x89d9
leaq -0x30(%rbp), %rdi
callq 0x32c0
leaq -0x40(%rbp), %rdi
callq 0x32c0
leaq -0x50(%rbp), %rdi
callq 0x32c0
movl -0x5c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)