// File: /workspace/github_c_makefile_star2_O0/cyb70289[P]tt/src/apn/integer/prime.c
// Function: isprime_miller_rabin
static bool isprime_miller_rabin(const _tt_word *n, int msbn, int rounds)
{
	_tt_word *buf;
	buf = malloc((msbn+2)*7*_tt_word_sz);

	_tt_word *m = buf;		/* (msbn+2) words */
	_tt_word *t = m + (msbn+2);	/* (msbn+2)*6 words */

	struct tt_int ni = _TT_INT_DECL(msbn, n);

	/* lambda = (2^31)^msbn, (2^63)^msbn */
	struct tt_int *lambda = tt_int_alloc();
	_tt_int_realloc(lambda, msbn+1);
	lambda->buf[msbn] = 1;
	lambda->msb = msbn + 1;

	/* u = -1/n % lambda, u >= 0 */
	struct tt_int *u = tt_int_alloc();
	tt_int_mod_inv(u, &ni, lambda);
	if (u->sign == 0)
		tt_int_sub(u, lambda, u);
	/* w = lambda % n */
	struct tt_int *w = tt_int_alloc();
	tt_int_div(NULL, w, lambda, &ni);

	/* n-1 = m * 2^k */
	int k = 0, msbm = msbn;
	memcpy(m, n, msbn*_tt_word_sz);
	m[0]--;
	/* Shift by word */
	while (m[0] == 0) {
		for (int i = 0; i < msbm-1; i++)
			m[i] = m[i+1];
		msbm--;
		k += _tt_word_bits;
	}
	/* Shift by bit */
	const int rsh = _tt_int_word_ctz(m[0]);
	msbm = _tt_int_shift_buf(m, msbm, -rsh);
	k += rsh;

	bool ret = true;
	struct tt_int *r = tt_int_alloc();
	_tt_int_realloc(r, msbn+2);
	while (rounds--) {
		r->msb = pick_rand(r->buf, n, msbn);
		/* r -> r*lambda % n */
		memset(t, 0, (msbn+2)*2*_tt_word_sz);
		int msbt = _tt_int_mul_buf(t, r->buf, r->msb,
				lambda->buf, lambda->msb);
		struct tt_int ti = _TT_INT_DECL(msbt, t);
		tt_int_div(NULL, r, &ti, &ni);

		if (!isprime_miller_rabin_1(n, msbn, r->buf, r->msb, m, msbm,
				k, u->buf, u->msb, w->buf, w->msb, t)) {
			ret = false;
			break;
		}
		_tt_int_zero(r);
	}

	free(buf);
	tt_int_free(lambda);
	tt_int_free(u);
	tt_int_free(w);
	tt_int_free(r);
	return ret;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
subq $0xd0, %rsp
movq %rdi, 0xc8(%rsp)
movl %esi, 0xc4(%rsp)
movl %edx, 0xc0(%rsp)
movl 0xc4(%rsp), %eax
addl $0x2, %eax
imull $0x7, %eax, %eax
shll $0x3, %eax
movslq %eax, %rdi
callq 0x1160
movq %rax, 0xb8(%rsp)
movq 0xb8(%rsp), %rax
movq %rax, 0xb0(%rsp)
movq 0xb0(%rsp), %rax
movl 0xc4(%rsp), %ecx
addl $0x2, %ecx
movslq %ecx, %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, 0xa8(%rsp)
movl $0x0, 0x90(%rsp)
movl 0xc4(%rsp), %eax
movl %eax, 0x94(%rsp)
movl 0xc4(%rsp), %eax
movl %eax, 0x98(%rsp)
movq 0xc8(%rsp), %rax
movq %rax, 0xa0(%rsp)
callq 0x6800
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rdi
movl 0xc4(%rsp), %esi
addl $0x1, %esi
callq 0x68d0
movq 0x88(%rsp), %rax
movq 0x10(%rax), %rax
movslq 0xc4(%rsp), %rcx
movq $0x1, (%rax,%rcx,8)
movl 0xc4(%rsp), %ecx
addl $0x1, %ecx
movq 0x88(%rsp), %rax
movl %ecx, 0x8(%rax)
callq 0x6800
movq %rax, 0x80(%rsp)
movq 0x80(%rsp), %rdi
movq 0x88(%rsp), %rdx
leaq 0x90(%rsp), %rsi
callq 0xcb90
movq 0x80(%rsp), %rax
cmpl $0x0, (%rax)
jne 0xd255
movq 0x80(%rsp), %rdi
movq 0x88(%rsp), %rsi
movq 0x80(%rsp), %rdx
callq 0xa890
callq 0x6800
movq %rax, 0x78(%rsp)
movq 0x78(%rsp), %rsi
movq 0x88(%rsp), %rdx
xorl %eax, %eax
movl %eax, %edi
leaq 0x90(%rsp), %rcx
callq 0xaa80
movl $0x0, 0x74(%rsp)
movl 0xc4(%rsp), %eax
movl %eax, 0x70(%rsp)
movq 0xb0(%rsp), %rdi
movq 0xc8(%rsp), %rsi
movl 0xc4(%rsp), %eax
shll $0x3, %eax
movslq %eax, %rdx
callq 0x1140
movq 0xb0(%rsp), %rax
movq (%rax), %rcx
addq $-0x1, %rcx
movq %rcx, (%rax)
movq 0xb0(%rsp), %rax
cmpq $0x0, (%rax)
jne 0xd335
movl $0x0, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
movl 0x70(%rsp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0xd31d
movq 0xb0(%rsp), %rax
movl 0x6c(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rdx
movq 0xb0(%rsp), %rax
movslq 0x6c(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0xd2da
movl 0x70(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x70(%rsp)
movl 0x74(%rsp), %eax
addl $0x3f, %eax
movl %eax, 0x74(%rsp)
jmp 0xd2c4
movq 0xb0(%rsp), %rax
movq (%rax), %rdi
callq 0x6b10
movl %eax, 0x68(%rsp)
movq 0xb0(%rsp), %rdi
movl 0x70(%rsp), %esi
xorl %edx, %edx
subl 0x68(%rsp), %edx
callq 0x6d10
movl %eax, 0x70(%rsp)
movl 0x68(%rsp), %eax
addl 0x74(%rsp), %eax
movl %eax, 0x74(%rsp)
movb $0x1, 0x67(%rsp)
callq 0x6800
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rdi
movl 0xc4(%rsp), %esi
addl $0x2, %esi
callq 0x68d0
movl 0xc0(%rsp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, 0xc0(%rsp)
cmpl $0x0, %eax
je 0xd50d
movq 0x58(%rsp), %rax
movq 0x10(%rax), %rdi
movq 0xc8(%rsp), %rsi
movl 0xc4(%rsp), %edx
callq 0xd6f0
movl %eax, %ecx
movq 0x58(%rsp), %rax
movl %ecx, 0x8(%rax)
movq 0xa8(%rsp), %rdi
movl 0xc4(%rsp), %eax
addl $0x2, %eax
shll %eax
shll $0x3, %eax
movslq %eax, %rdx
xorl %esi, %esi
callq 0x10e0
movq 0xa8(%rsp), %rdi
movq 0x58(%rsp), %rax
movq 0x10(%rax), %rsi
movq 0x58(%rsp), %rax
movl 0x8(%rax), %edx
movq 0x88(%rsp), %rax
movq 0x10(%rax), %rcx
movq 0x88(%rsp), %rax
movl 0x8(%rax), %r8d
callq 0x8be0
movl %eax, 0x54(%rsp)
movl $0x0, 0x38(%rsp)
movl 0x54(%rsp), %eax
movl %eax, 0x3c(%rsp)
movl 0x54(%rsp), %eax
movl %eax, 0x40(%rsp)
movq 0xa8(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x58(%rsp), %rsi
xorl %eax, %eax
movl %eax, %edi
leaq 0x38(%rsp), %rdx
leaq 0x90(%rsp), %rcx
callq 0xaa80
movq 0xc8(%rsp), %rdi
movl 0xc4(%rsp), %esi
movq 0x58(%rsp), %rax
movq 0x10(%rax), %rdx
movq 0x58(%rsp), %rax
movl 0x8(%rax), %ecx
movq 0xb0(%rsp), %r8
movl 0x70(%rsp), %r9d
movl 0x74(%rsp), %ebp
movq 0x80(%rsp), %rax
movq 0x10(%rax), %r14
movq 0x80(%rsp), %rax
movl 0x8(%rax), %ebx
movq 0x78(%rsp), %rax
movq 0x10(%rax), %r11
movq 0x78(%rsp), %rax
movl 0x8(%rax), %r10d
movq 0xa8(%rsp), %rax
movl %ebp, (%rsp)
movq %r14, 0x8(%rsp)
movl %ebx, 0x10(%rsp)
movq %r11, 0x18(%rsp)
movl %r10d, 0x20(%rsp)
movq %rax, 0x28(%rsp)
callq 0xd870
testb $0x1, %al
jne 0xd4fe
movb $0x0, 0x67(%rsp)
jmp 0xd50d
movq 0x58(%rsp), %rdi
callq 0x6a60
jmp 0xd393
movq 0xb8(%rsp), %rdi
callq 0x1030
movq 0x88(%rsp), %rdi
callq 0x68b0
movq 0x80(%rsp), %rdi
callq 0x68b0
movq 0x78(%rsp), %rdi
callq 0x68b0
movq 0x58(%rsp), %rdi
callq 0x68b0
movb 0x67(%rsp), %al
andb $0x1, %al
addq $0xd0, %rsp
popq %rbx
popq %r14
popq %rbp
retq
nopw (%rax,%rax)