// File: /workspace/github_c_makefile_star2_O3/hansvanstaveren[P]BigDeal/binomial.c
// Function: code_to_hand
void
code_to_hand(dl_num *dnp, dl_int *dip)
/*
 * This function converts a given number to its associated bridge-deal.
 * Read the file Godel.pdf for an explanation of the code. The
 * variable-names used in the comments refer to the variable-names
 * that were used in the pseudo-code in Godel.pdf.
 */
{
	int i,j,a,b;
	byte c[L];
	byte g[L];
	byte tmp1[L],tmp2[L],tmp3[L];
	int compass;

	/*
	 * set g_{-1} = g
	 */
	mp96_assign(g, dnp->dn_num);

	for (compass=COMPASS_NORTH; compass<NCOMPASS; compass++) {
		/*
		 * Computation of an appropriate constant for the given
		 * compass direction. The constant is equal to:
		 * 39_over_13 x 26_over_13   for North,
		 * 26_over_13                for East,
		 * 1                         for South.
		 *
		 * Code continues for West who automatically gets 13 zeroes
		 */
		mp96_one(c);
		for (i=2; i<=COMPASS_WEST-compass; i++) {
			n_over_k(i*13, 13, tmp1);
			mp96_mul(c, tmp1, c);
		}

		/*
		 * set a_{-1} = 0
		 */
		a = 0;
		for (j=0; j<NCARDSPERHAND; j++) {
			/* 
			 * Computation of a_j, x_j and g_j.
			 * a_j is computed by setting variable b to a_{j-1} and
			 * incrementing it until it reaches the value a_j.
			 */
			n_over_k(13*(NCOMPASS-compass)-a-j, 13-j, tmp1);

			/*
			 * b is set to a_{j-1} and up
			 */
			for(b=a; ; b++) {
				n_over_k(13*(NCOMPASS-compass)-b-1-j, 13-j, tmp2);
				mp96_sub(tmp2, tmp1, tmp2);
				mp96_mul(tmp2, tmp2, c);
				/*
				 * Check if b < a_j, i.e. if tmp2 > g
				 */
				if (mp96_cmp(tmp2, g) > 0)
					break;
			}
			n_over_k(13*(NCOMPASS-compass)-a-j, 13-j, tmp1);
			n_over_k(13*(NCOMPASS-compass)-b-j, 13-j, tmp2);
			mp96_sub(tmp3, tmp1, tmp2);
			/*
			 * tmp1 is assigned the value x_j
			 */
			mp96_mul(tmp1, tmp3, c);
			/*
			 * g_j = g_{j-1} - x_j
			 */
			mp96_sub(g, g, tmp1);
			dip->di_hand[compass][j] = b;
			/*
			 * a is set to a_j
			 */
			a = b;
		}
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rsi, 0x30(%rsp)
movq %rdi, %rsi
leaq 0x4c(%rsp), %rdi
callq 0x3792
movl $0x2, %r15d
movl $0xffffffcb, %ecx       # imm = 0xFFFFFFCB
movl $0x33, 0x8(%rsp)
xorl %ebx, %ebx
leaq 0x58(%rsp), %rdi
leaq 0x64(%rsp), %r14
leaq 0x7c(%rsp), %r13
movl %ecx, 0xc(%rsp)
movq %rdi, %r12
callq 0x377f
movq %rbx, 0x28(%rsp)
cmpq $0x1, %rbx
ja 0x3a46
movl $0x1a, %ebx
movl %r15d, %ebp
movl %ebx, %edi
movl $0xd, %esi
movq %r14, %rdx
callq 0x397f
movq %r12, %rdi
movq %r14, %rsi
movq %r12, %rdx
callq 0x3816
addl $0xd, %ebx
decl %ebp
jne 0x3a22
movl %r15d, 0x14(%rsp)
movl $0x4, %eax
movq 0x28(%rsp), %rdx
subl %edx, %eax
leal (%rax,%rax,2), %ecx
leal (%rax,%rcx,4), %eax
movl %eax, 0x18(%rsp)
xorl %ecx, %ecx
leaq (%rdx,%rdx,2), %rax
leaq (%rdx,%rax,4), %rax
addq 0x30(%rsp), %rax
movq %rax, 0x38(%rsp)
movl 0x8(%rsp), %ebp
movl 0xc(%rsp), %r12d
xorl %r15d, %r15d
movq %r14, %rbx
movl 0x18(%rsp), %edi
subl %r15d, %edi
subl %ecx, %edi
movl $0xd, %esi
movq %rcx, 0x40(%rsp)
subl %ecx, %esi
movl %edi, 0x1c(%rsp)
movl %esi, 0x10(%rsp)
movq %rbx, %rdx
callq 0x397f
leal -0x1(%r15), %eax
movl %ebp, 0x24(%rsp)
movl %ebp, %r14d
subl %r15d, %r14d
movl %r12d, 0x20(%rsp)
addl %r12d, %r15d
movl %r15d, %ebp
movl %eax, %r15d
leaq 0x58(%rsp), %r12
movl %r14d, %edi
movl 0x10(%rsp), %esi
movq %r13, %rdx
callq 0x397f
movq %r13, %rdi
movq %rbx, %rsi
movq %r13, %rdx
callq 0x37cd
movq %r13, %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0x3816
movq %r13, %rdi
leaq 0x4c(%rsp), %rsi
callq 0x37f8
incl %r15d
incl %ebp
decl %r14d
testl %eax, %eax
jle 0x3aca
movl 0x1c(%rsp), %edi
movl 0x10(%rsp), %r14d
movl %r14d, %esi
movq %rbx, %rdx
callq 0x397f
negl %ebp
movl %ebp, %edi
movl %r14d, %esi
movq %r13, %rdx
callq 0x397f
leaq 0x70(%rsp), %rbx
movq %rbx, %rdi
leaq 0x64(%rsp), %r14
movq %r14, %rsi
movq %r13, %rdx
callq 0x37cd
movq %r14, %rdi
movq %rbx, %rsi
movq %r12, %rdx
callq 0x3816
leaq 0x4c(%rsp), %rdi
movq %rdi, %rsi
movq %r14, %rdx
callq 0x37cd
movq 0x40(%rsp), %rcx
movq 0x38(%rsp), %rax
movb %r15b, (%rcx,%rax)
incq %rcx
movl 0x20(%rsp), %r12d
incl %r12d
movl 0x24(%rsp), %ebp
decl %ebp
cmpq $0xd, %rcx
movq %r14, %rbx
jne 0x3a84
movq %rbx, %r14
movq 0x28(%rsp), %rbx
incq %rbx
movl 0x14(%rsp), %r15d
decl %r15d
movl 0xc(%rsp), %ecx
addl $0xd, %ecx
addl $-0xd, 0x8(%rsp)
cmpq $0x4, %rbx
leaq 0x58(%rsp), %rdi
jne 0x3a03
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop