// File: /workspace/github_c_makefile_star2_O1/janmojzis[P]mcencrypt/benes.c
// Function: apply_benes
void apply_benes(unsigned char * r, const unsigned char * bits, int rev)
{
	int i, iter, inc;

	unsigned char *r_ptr = r;
	const unsigned char *bits_ptr;

	uint64_t r_int_v[2][64];
	uint64_t r_int_h[2][64];
	uint64_t b_int_v[64];
	uint64_t b_int_h[64];

	/* // */

	if (rev) { bits_ptr = bits + 12288; inc = -1024; }
	else     { bits_ptr = bits;         inc = 0;    }
		
	for (i = 0; i < 64; i++)
	{
		r_int_v[0][i] = load8(r_ptr + i*16 + 0);
		r_int_v[1][i] = load8(r_ptr + i*16 + 8);
	}

	transpose_64x64(r_int_h[0], r_int_v[0]);
	transpose_64x64(r_int_h[1], r_int_v[1]);

	for (iter = 0; iter <= 6; iter++)
	{
		for (i = 0; i < 64; i++)
		{
			b_int_v[i] = load8(bits_ptr); bits_ptr += 8;
		}

		bits_ptr += inc;

		transpose_64x64(b_int_h, b_int_v);
	
		layer_ex(r_int_h[0], b_int_h, iter);
	}

	transpose_64x64(r_int_v[0], r_int_h[0]);
	transpose_64x64(r_int_v[1], r_int_h[1]);

	for (iter = 0; iter <= 5; iter++) 
	{
		for (i = 0; i < 64; i++) { b_int_v[i] = load8(bits_ptr); bits_ptr += 8; }
		bits_ptr += inc;

		layer_in(r_int_v, b_int_v, iter);
	}

	for (iter = 4; iter >= 0; iter--) 
	{
		for (i = 0; i < 64; i++) { b_int_v[i] = load8(bits_ptr); bits_ptr += 8; }
		bits_ptr += inc;

		layer_in(r_int_v, b_int_v, iter);
	}

	transpose_64x64(r_int_h[0], r_int_v[0]);
	transpose_64x64(r_int_h[1], r_int_v[1]);

	for (iter = 6; iter >= 0; iter--)
	{
		for (i = 0; i < 64; i++)
		{
			b_int_v[i] = load8(bits_ptr); bits_ptr += 8;
		}

		bits_ptr += inc;

		transpose_64x64(b_int_h, b_int_v);

		layer_ex(r_int_h[0], b_int_h, iter);
	}

	transpose_64x64(r_int_v[0], r_int_h[0]);
	transpose_64x64(r_int_v[1], r_int_h[1]);

	for (i = 0; i < 64; i++)
	{
		store8(r_ptr + i*16 + 0, r_int_v[0][i]);
		store8(r_ptr + i*16 + 8, r_int_v[1][i]);
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc28, %rsp            # imm = 0xC28
movl %edx, %ebp
movq %rsi, %r12
movq %rdi, %rbx
xorl %r13d, %r13d
testl %edx, %edx
movl $0x3000, %r15d          # imm = 0x3000
cmoveq %r13, %r15
movq %rdi, %r14
movq %r14, %rdi
callq 0x6b74
movq %rax, 0x220(%rsp,%r13,8)
leaq 0x8(%r14), %rdi
callq 0x6b74
movq %rax, 0x420(%rsp,%r13,8)
incq %r13
addq $0x10, %r14
cmpq $0x40, %r13
jne 0x152f
xorl %eax, %eax
testl %ebp, %ebp
sete %al
shll $0xa, %eax
addq $-0x400, %rax           # imm = 0xFC00
movq %rax, 0x8(%rsp)
addq %r15, %r12
leaq 0x620(%rsp), %r15
leaq 0x220(%rsp), %r14
movq %r15, %rdi
movq %r14, %rsi
callq 0x6aa0
movl $0x200, %eax            # imm = 0x200
leaq (%r15,%rax), %rdi
addq %rax, %r14
movq %rdi, 0x10(%rsp)
movq %r14, 0x18(%rsp)
movq %r14, %rsi
callq 0x6aa0
xorl %r15d, %r15d
leaq 0xa20(%rsp), %r14
xorl %ebp, %ebp
movq %r12, %r13
movq %r13, %rdi
callq 0x6b74
movq %rax, 0x20(%rsp,%rbp,8)
addq $0x8, %r13
incq %rbp
cmpq $0x40, %rbp
jne 0x15be
movq 0x8(%rsp), %rax
leaq (%rax,%r13), %r12
movq %r14, %rdi
leaq 0x20(%rsp), %rsi
callq 0x6aa0
leaq 0x620(%rsp), %rdi
movq %r14, %rsi
movl %r15d, %edx
callq 0x17b8
incl %r15d
cmpl $0x7, %r15d
jne 0x15b9
leaq 0x220(%rsp), %rdi
leaq 0x620(%rsp), %rsi
callq 0x6aa0
movq 0x18(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0x6aa0
addq 0x8(%rsp), %r13
xorl %r14d, %r14d
leaq 0x20(%rsp), %r15
xorl %r12d, %r12d
movq %r13, %rbp
movq %rbp, %rdi
callq 0x6b74
movq %rax, 0x20(%rsp,%r12,8)
addq $0x8, %rbp
incq %r12
cmpq $0x40, %r12
jne 0x1641
movq 0x8(%rsp), %rax
leaq (%rax,%rbp), %r13
leaq 0x220(%rsp), %rdi
movq %r15, %rsi
movl %r14d, %edx
callq 0x1822
incl %r14d
cmpl $0x6, %r14d
jne 0x163b
addq 0x8(%rsp), %rbp
movl $0x4, %r14d
leaq 0x20(%rsp), %r13
xorl %r15d, %r15d
movq %rbp, %r12
movq %r12, %rdi
callq 0x6b74
movq %rax, 0x20(%rsp,%r15,8)
addq $0x8, %r12
incq %r15
cmpq $0x40, %r15
jne 0x1696
movq 0x8(%rsp), %rax
leaq (%r12,%rax), %rbp
leaq 0x220(%rsp), %rdi
movq %r13, %rsi
movl %r14d, %edx
callq 0x1822
subl $0x1, %r14d
jae 0x1690
leaq 0x620(%rsp), %rdi
leaq 0x220(%rsp), %rsi
callq 0x6aa0
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %rsi
callq 0x6aa0
addq 0x8(%rsp), %r12
movl $0x6, %ebp
leaq 0xa20(%rsp), %r14
leaq 0x20(%rsp), %r15
xorl %r13d, %r13d
movq %r12, %rdi
callq 0x6b74
movq %rax, 0x20(%rsp,%r13,8)
addq $0x8, %r12
incq %r13
cmpq $0x40, %r13
jne 0x1710
addq 0x8(%rsp), %r12
movq %r14, %rdi
movq %r15, %rsi
callq 0x6aa0
leaq 0x620(%rsp), %rdi
movq %r14, %rsi
movl %ebp, %edx
callq 0x17b8
subl $0x1, %ebp
jae 0x170d
leaq 0x220(%rsp), %rdi
leaq 0x620(%rsp), %rsi
callq 0x6aa0
movq 0x18(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0x6aa0
xorl %r14d, %r14d
movq 0x220(%rsp,%r14,8), %rsi
movq %rbx, %rdi
callq 0x6b70
leaq 0x8(%rbx), %rdi
movq 0x420(%rsp,%r14,8), %rsi
callq 0x6b70
incq %r14
addq $0x10, %rbx
cmpq $0x40, %r14
jne 0x1778
addq $0xc28, %rsp            # imm = 0xC28
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq