// File: /workspace/github_c_makefile_star2_O2/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, %r14
xorl %eax, %eax
testl %edx, %edx
movl $0x3000, %r12d          # imm = 0x3000
cmoveq %rax, %r12
movq %rdi, %rbx
pushq $0x40
popq %r13
movq %rdi, %r15
cmpq $0x80, %r13
je 0x1545
movq %r15, %rdi
callq 0x65d4
movq %rax, (%rsp,%r13,8)
leaq 0x8(%r15), %rdi
callq 0x65d4
movq %rax, 0x200(%rsp,%r13,8)
incq %r13
addq $0x10, %r15
jmp 0x1516
xorl %r13d, %r13d
testl %ebp, %ebp
sete %r13b
shll $0xa, %r13d
addq $-0x400, %r13           # imm = 0xFC00
addq %r12, %r14
leaq 0x600(%rsp), %rdi
leaq 0x200(%rsp), %rsi
callq 0x64f4
leaq 0x800(%rsp), %rdi
leaq 0x400(%rsp), %rsi
callq 0x64f4
xorl %ebp, %ebp
leaq 0xa00(%rsp), %r15
cmpl $0x7, %ebp
je 0x15db
xorl %r12d, %r12d
cmpq $0x200, %r12            # imm = 0x200
je 0x15b4
leaq (%r14,%r12), %rdi
callq 0x65d4
movq %rax, (%rsp,%r12)
addq $0x8, %r12
jmp 0x1598
addq %r13, %r14
addq %r12, %r14
movq %r15, %rdi
movq %rsp, %rsi
callq 0x64f4
leaq 0x600(%rsp), %rdi
movq %r15, %rsi
movl %ebp, %edx
callq 0x1780
incl %ebp
jmp 0x1590
leaq 0x200(%rsp), %rdi
leaq 0x600(%rsp), %rsi
callq 0x64f4
leaq 0x400(%rsp), %rdi
leaq 0x800(%rsp), %rsi
callq 0x64f4
xorl %r15d, %r15d
movq %rsp, %r12
cmpl $0x6, %r15d
je 0x164d
xorl %ebp, %ebp
cmpq $0x200, %rbp            # imm = 0x200
je 0x162f
leaq (%r14,%rbp), %rdi
callq 0x65d4
movq %rax, (%rsp,%rbp)
addq $0x8, %rbp
jmp 0x1613
addq %r13, %r14
addq %rbp, %r14
leaq 0x200(%rsp), %rdi
movq %r12, %rsi
movl %r15d, %edx
callq 0x17e2
incl %r15d
jmp 0x160b
pushq $0x4
popq %rbp
movq %rsp, %r12
testl %ebp, %ebp
js 0x1692
xorl %r15d, %r15d
cmpq $0x200, %r15            # imm = 0x200
je 0x1676
leaq (%r14,%r15), %rdi
callq 0x65d4
movq %rax, (%rsp,%r15)
addq $0x8, %r15
jmp 0x165a
addq %r13, %r14
addq %r15, %r14
leaq 0x200(%rsp), %rdi
movq %r12, %rsi
movl %ebp, %edx
callq 0x17e2
decl %ebp
jmp 0x1653
leaq 0x600(%rsp), %rdi
leaq 0x200(%rsp), %rsi
callq 0x64f4
leaq 0x800(%rsp), %rdi
leaq 0x400(%rsp), %rsi
callq 0x64f4
pushq $0x6
popq %rbp
leaq 0xa00(%rsp), %r15
testl %ebp, %ebp
js 0x1711
xorl %r12d, %r12d
cmpq $0x200, %r12            # imm = 0x200
je 0x16ea
leaq (%r14,%r12), %rdi
callq 0x65d4
movq %rax, (%rsp,%r12)
addq $0x8, %r12
jmp 0x16ce
addq %r13, %r14
addq %r12, %r14
movq %r15, %rdi
movq %rsp, %rsi
callq 0x64f4
leaq 0x600(%rsp), %rdi
movq %r15, %rsi
movl %ebp, %edx
callq 0x1780
decl %ebp
jmp 0x16c7
leaq 0x200(%rsp), %rdi
leaq 0x600(%rsp), %rsi
callq 0x64f4
leaq 0x400(%rsp), %rdi
leaq 0x800(%rsp), %rsi
callq 0x64f4
pushq $0x40
popq %r14
cmpq $0x80, %r14
je 0x176e
movq (%rsp,%r14,8), %rsi
movq %rbx, %rdi
callq 0x65d0
leaq 0x8(%rbx), %rdi
movq 0x200(%rsp,%r14,8), %rsi
callq 0x65d0
incq %r14
addq $0x10, %rbx
jmp 0x173f
addq $0xc08, %rsp            # imm = 0xC08
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq