// File: /workspace/github_c_makefile_star2_O3/kernfel[P]fNEAT/cppn.c
// Function: read_CPPN
double read_CPPN( CPPN *net, const struct NEAT_Params *params, double *source, double *target, double *output ) {
	int i,j;
	int num_nodes = net->num_inputs+net->num_hidden+net->num_outputs;
	
	// Set input values
	for ( i=0; i<DIMENSIONS; i++ ) {
		net->nodes[i].activation = CPPN_func(net->nodes[i].func, source[i]);
	}
	for ( ; i<2*DIMENSIONS; i++ ) {
		net->nodes[i].activation = CPPN_func(net->nodes[i].func, target[i-DIMENSIONS]);
	}
	if ( params->flags & CFL_USE_DIST ) {
		double d=0.0;
		for ( j=0; j<DIMENSIONS; j++ )
			d += pow(source[j]-target[j], 2);
		net->nodes[i].activation = CPPN_func(net->nodes[i].func, (params->flags & CFL_SQUARE_DIST) ? d : sqrt(d));
		i++;
	}
	if ( params->flags & CFL_USE_BIAS ) {
		net->nodes[i].activation = CPPN_func(net->nodes[i].func, 1.0);
	}
	
	// Flush
	for ( i=net->num_inputs; i<num_nodes; i++ ) {
		net->nodes[i].activation = 0.0;
	}
	
	// Cycle through the net until nothing changes or num_activations is reached
	int k, k_incr, k_max;
	if ( params->flags & CFL_ALLOW_RECURRENCE ) {
		k_incr = 1;
		k_max = params->num_activations;
	} else {
		k_incr = 1;
		k_max = 0;
	}
	
	double diff=0;
	for ( k=0; !k_max || k<k_max; k+=k_incr ) {
		diff = 0.0;
		
		// Go through each node
		for ( i=net->num_inputs; i<num_nodes; i++ ) {
			double a=0.0;
			
			// Find each of its input links
			for ( j=0; j<net->num_links; j++ ) {
				if ( net->links[j].to == i ) {
					a += net->links[j].weight * net->nodes[net->links[j].from].activation;
				}
			}
			a = CPPN_func( net->nodes[i].func, a );
			diff += fabs( a - net->nodes[i].activation );
			net->nodes[i].activation = a;
		}

		if ( diff == 0.0 )
			break;
	}
	
	for ( i=0; i<net->num_outputs; i++ ) {
		output[i] = net->nodes[i+net->num_inputs].activation;
	}

	return diff;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %r8, 0x10(%rsp)
movq %rcx, %r12
movq %rdx, %r13
movq %rsi, 0x8(%rsp)
movq %rdi, %r14
movl 0x8(%rdi), %ebx
movl 0x10(%rdi), %eax
movl %eax, 0x4(%rsp)
movl 0xc(%rdi), %eax
movl %eax, (%rsp)
movq (%rdi), %rax
movb $0x1, %bpl
xorl %ecx, %ecx
movq %rcx, %r15
shlq $0x4, %r15
movl (%rax,%r15), %edi
movsd (%r13,%rcx,8), %xmm0
callq 0x29af
movq (%r14), %rax
movsd %xmm0, 0x8(%rax,%r15)
movl $0x1, %ecx
testb $0x1, %bpl
movl $0x0, %ebp
jne 0x2a5e
addl %ebx, 0x4(%rsp)
xorl %ebx, %ebx
movl 0x20(%rax,%rbx,2), %edi
movsd (%r12,%rbx), %xmm0
callq 0x29af
movq (%r14), %rax
movsd %xmm0, 0x28(%rax,%rbx,2)
addq $0x8, %rbx
cmpq $0x10, %rbx
jne 0x2a95
movq 0x8(%rsp), %rbp
movl (%rbp), %ecx
movl $0x4, %ebx
testb $0x1, %cl
je 0x2b2e
xorpd %xmm0, %xmm0
movb $0x1, %dl
xorl %esi, %esi
movsd (%r13,%rsi,8), %xmm1
subsd (%r12,%rsi,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm0
movl $0x1, %esi
testb $0x1, %dl
movl $0x0, %edx
jne 0x2ad1
movl 0x40(%rax), %ebp
testb $0x2, %cl
jne 0x2b12
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x2b0d
sqrtsd %xmm0, %xmm0
jmp 0x2b12
callq 0x1180
movl %ebp, %edi
callq 0x29af
movq (%r14), %rax
movsd %xmm0, 0x48(%rax)
movq 0x8(%rsp), %rbp
movl (%rbp), %ecx
movl $0x5, %ebx
movl (%rsp), %edx
addl %edx, 0x4(%rsp)
testb $0x4, %cl
je 0x2b56
shll $0x4, %ebx
movl (%rax,%rbx), %edi
movsd 0x45e8(%rip), %xmm0     # 0x7130
callq 0x29af
movq (%r14), %rax
movsd %xmm0, 0x8(%rax,%rbx)
movslq 0x8(%r14), %rdx
movl 0x4(%rsp), %ecx
movslq %ecx, %r12
cmpl %ecx, %edx
jge 0x2c10
movq %r12, %rsi
subq %rdx, %rsi
leaq 0x1(%rsi), %rcx
andq $-0x2, %rcx
decq %rsi
movq %rsi, %xmm0
pshufd $0x44, %xmm0, %xmm0     # xmm0 = xmm0[0,1,0,1]
shlq $0x4, %rdx
addq %rax, %rdx
addq $0x18, %rdx
xorl %esi, %esi
movdqa 0x46c7(%rip), %xmm1     # 0x7260
movdqa 0x46cf(%rip), %xmm2     # 0x7270
pxor %xmm2, %xmm0
pcmpeqd %xmm3, %xmm3
movq %rsi, %xmm4
pshufd $0x44, %xmm4, %xmm4     # xmm4 = xmm4[0,1,0,1]
por %xmm1, %xmm4
pxor %xmm2, %xmm4
movdqa %xmm4, %xmm5
pcmpgtd %xmm0, %xmm5
pcmpeqd %xmm0, %xmm4
pshufd $0xf5, %xmm4, %xmm6     # xmm6 = xmm4[1,1,3,3]
pand %xmm5, %xmm6
pshufd $0xf5, %xmm5, %xmm4     # xmm4 = xmm5[1,1,3,3]
por %xmm6, %xmm4
movd %xmm4, %edi
notl %edi
testb $0x1, %dil
je 0x2bed
movq $0x0, -0x10(%rdx)
pxor %xmm3, %xmm4
pextrw $0x4, %xmm4, %edi
testb $0x1, %dil
je 0x2c03
movq $0x0, (%rdx)
addq $0x2, %rsi
addq $0x20, %rdx
cmpq %rsi, %rcx
jne 0x2ba9
xorl %r13d, %r13d
movb $0x1, (%rsp)
testb $0x8, (%rbp)
movl $0x0, %r15d
je 0x2c34
movl 0x4c(%rbp), %r15d
testl %r15d, %r15d
sete (%rsp)
js 0x2cf2
movslq 0x8(%r14), %rbx
cmpl 0x4(%rsp), %ebx
jge 0x2cf2
xorpd %xmm1, %xmm1
movsd %xmm1, 0x8(%rsp)
movslq 0x20(%r14), %rcx
xorpd %xmm0, %xmm0
testq %rcx, %rcx
jle 0x2c8b
movq 0x18(%r14), %rdx
shlq $0x5, %rcx
xorl %esi, %esi
cmpl %ebx, 0x8(%rdx,%rsi)
jne 0x2c82
movsd 0x10(%rdx,%rsi), %xmm1
movslq 0x4(%rdx,%rsi), %rdi
shlq $0x4, %rdi
mulsd 0x8(%rax,%rdi), %xmm1
addsd %xmm1, %xmm0
addq $0x20, %rsi
cmpq %rsi, %rcx
jne 0x2c63
movq %rbx, %rbp
shlq $0x4, %rbp
movl (%rax,%rbp), %edi
callq 0x29af
movq (%r14), %rax
movapd %xmm0, %xmm1
subsd 0x8(%rax,%rbp), %xmm1
andpd 0x45e1(%rip), %xmm1     # 0x7290
movsd 0x8(%rsp), %xmm2
addsd %xmm1, %xmm2
movapd %xmm2, %xmm1
movsd %xmm0, 0x8(%rax,%rbp)
incq %rbx
cmpq %r12, %rbx
jl 0x2c46
ucomisd 0x45e1(%rip), %xmm1     # 0x72b8
jne 0x2cdb
jnp 0x2cf6
incl %r13d
cmpl %r15d, %r13d
setb %cl
orb (%rsp), %cl
cmpb $0x1, %cl
je 0x2c34
jmp 0x2cf6
xorpd %xmm1, %xmm1
movslq 0xc(%r14), %rcx
testq %rcx, %rcx
movq 0x10(%rsp), %rsi
jle 0x2d2c
movslq 0x8(%r14), %rdx
shlq $0x4, %rdx
addq %rdx, %rax
addq $0x8, %rax
shlq $0x3, %rcx
xorl %edx, %edx
movsd (%rax,%rdx,2), %xmm0
movsd %xmm0, (%rsi,%rdx)
addq $0x8, %rdx
cmpq %rdx, %rcx
jne 0x2d19
movapd %xmm1, %xmm0
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq