// File: /workspace/github_c_makefile_star2_O3/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 $0xc08, %rsp            # imm = 0xC08
movl %edx, %ebp
movq %rsi, %r12
movq %rdi, %rbx
xorl %r15d, %r15d
testl %edx, %edx
movl $0x3000, %r13d          # imm = 0x3000
cmoveq %r15, %r13
movq %rdi, %r14
movq %r14, %rdi
callq 0x6f3c
movq %rax, 0x200(%rsp,%r15,8)
leaq 0x8(%r14), %rdi
callq 0x6f3c
movq %rax, 0x400(%rsp,%r15,8)
incq %r15
addq $0x10, %r14
cmpq $0x40, %r15
jne 0x152f
xorl %r15d, %r15d
testl %ebp, %ebp
sete %r15b
shll $0xa, %r15d
addq $-0x400, %r15           # imm = 0xFC00
addq %r13, %r12
leaq 0x600(%rsp), %rdi
leaq 0x200(%rsp), %rsi
callq 0x6e68
leaq 0x800(%rsp), %rdi
leaq 0x400(%rsp), %rsi
callq 0x6e68
xorl %r14d, %r14d
xorl %ebp, %ebp
movq %r12, %r13
movq %r13, %rdi
callq 0x6f3c
movq %rax, (%rsp,%rbp,8)
addq $0x8, %r13
incq %rbp
cmpq $0x40, %rbp
jne 0x15a6
leaq (%r15,%r13), %r12
leaq 0xa00(%rsp), %rbp
movq %rbp, %rdi
movq %rsp, %rsi
callq 0x6e68
leaq 0x600(%rsp), %rdi
movq %rbp, %rsi
movl %r14d, %edx
callq 0x178e
incl %r14d
cmpl $0x7, %r14d
jne 0x15a1
leaq 0x200(%rsp), %rdi
leaq 0x600(%rsp), %rsi
callq 0x6e68
leaq 0x400(%rsp), %rdi
leaq 0x800(%rsp), %rsi
callq 0x6e68
addq %r15, %r13
xorl %r14d, %r14d
xorl %r12d, %r12d
movq %r13, %rbp
movq %rbp, %rdi
callq 0x6f3c
movq %rax, (%rsp,%r12,8)
addq $0x8, %rbp
incq %r12
cmpq $0x40, %r12
jne 0x1628
leaq (%r15,%rbp), %r13
leaq 0x200(%rsp), %rdi
movq %rsp, %rsi
movl %r14d, %edx
callq 0x17f8
incl %r14d
cmpl $0x6, %r14d
jne 0x1622
addq %r15, %rbp
movl $0x4, %r14d
xorl %r13d, %r13d
movq %rbp, %r12
movq %r12, %rdi
callq 0x6f3c
movq %rax, (%rsp,%r13,8)
addq $0x8, %r12
incq %r13
cmpq $0x40, %r13
jne 0x1670
leaq (%r12,%r15), %rbp
leaq 0x200(%rsp), %rdi
movq %rsp, %rsi
movl %r14d, %edx
callq 0x17f8
subl $0x1, %r14d
jae 0x166a
leaq 0x600(%rsp), %rdi
leaq 0x200(%rsp), %rsi
callq 0x6e68
leaq 0x800(%rsp), %rdi
leaq 0x400(%rsp), %rsi
callq 0x6e68
addq %r15, %r12
movl $0x6, %ebp
leaq 0xa00(%rsp), %r14
xorl %r13d, %r13d
movq %r12, %rdi
callq 0x6f3c
movq %rax, (%rsp,%r13,8)
addq $0x8, %r12
incq %r13
cmpq $0x40, %r13
jne 0x16e3
addq %r15, %r12
movq %r14, %rdi
movq %rsp, %rsi
callq 0x6e68
leaq 0x600(%rsp), %rdi
movq %r14, %rsi
movl %ebp, %edx
callq 0x178e
subl $0x1, %ebp
jae 0x16e0
leaq 0x200(%rsp), %rdi
leaq 0x600(%rsp), %rsi
callq 0x6e68
leaq 0x400(%rsp), %rdi
leaq 0x800(%rsp), %rsi
callq 0x6e68
xorl %r14d, %r14d
movq 0x200(%rsp,%r14,8), %rsi
movq %rbx, %rdi
callq 0x6f38
leaq 0x8(%rbx), %rdi
movq 0x400(%rsp,%r14,8), %rsi
callq 0x6f38
incq %r14
addq $0x10, %rbx
cmpq $0x40, %r14
jne 0x174e
addq $0xc08, %rsp            # imm = 0xC08
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq