// File: ksabry[P]bfbrute/src/DataCache.h
// Function: DataCache<32ul, 12ul>::AddComposite(AlignedData<32ul>*, AlignedData<32ul>*, char*, char*, unsigned int, unsigned int)
void AddComposite(
		AlignedData<data_size>* leftData, AlignedData<data_size>* rightData, 
		char * leftProgram, char * rightProgram, 
		unsigned leftProgramSize, unsigned rightProgramSize)
	{
		//char leftDataIndex = leftData[0] - startDataIndex;
		//char rightDataIndex = rightData[0] - startDataIndex;

		currentDataIdx = leftData->idx + rightData->idx;
		if (currentDataIdx < lowDataIdx || currentDataIdx >= highDataIdx)
			return;

		if (leftData->idx > 0)
		{
			for (uint8_t rightI = data_size - leftData->idx; rightI < data_size; rightI++)
				if (rightData->data[rightI] != 0)
					return;
			memcpy(currentData, leftData->data, data_size);
			for (uint8_t rightI = 0; rightI < data_size - leftData->idx; rightI++)
				currentData[rightI + leftData->idx] += rightData->data[rightI];
		}
		else
		{
			for (uint8_t i = 0; i < -leftData->idx; i++)
				if (rightData->data[i] != 0)
					return;
			memcpy(currentData, leftData->data, data_size);
			for (uint8_t rightI = -leftData->idx; rightI < data_size; rightI++)
				currentData[rightI + leftData->idx] += rightData->data[rightI];
		}

		memcpy(currentProgram, leftProgram, leftProgramSize);
		memcpy(currentProgram + leftProgramSize, rightProgram, rightProgramSize);
		
		currentDataStart = Min(leftData->start, rightData->start + leftData->idx);
		currentDataEnd = Max(leftData->end, rightData->end + leftData->idx);

		if (currentDataStart > 10000 || currentDataEnd > 10000)
		{
			volatile int x = 0;
		}

		AddData();
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movl 0x10(%rbp), %eax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movl %r9d, -0x2c(%rbp)
movq -0x8(%rbp), %rcx
movq %rcx, -0x50(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x18(%rbp), %rdx
addq 0x20(%rdx), %rax
movq %rax, 0x1c0(%rcx)
movq 0x1c0(%rcx), %rax
cmpq 0x8(%rcx), %rax
jl 0xa7d0
movq -0x50(%rbp), %rcx
movq 0x1c0(%rcx), %rax
cmpq 0x10(%rcx), %rax
jl 0xa7d5
jmp 0xaa31
movq -0x10(%rbp), %rax
cmpq $0x0, 0x20(%rax)
jle 0xa8a9
movq -0x10(%rbp), %rcx
movl $0x20, %eax
subq 0x20(%rcx), %rax
movb %al, -0x2d(%rbp)
movzbl -0x2d(%rbp), %eax
cmpq $0x20, %rax
jae 0xa820
movq -0x18(%rbp), %rax
movzbl -0x2d(%rbp), %ecx
movzbl (%rax,%rcx), %eax
cmpl $0x0, %eax
je 0xa814
jmp 0xaa31
jmp 0xa816
movb -0x2d(%rbp), %al
addb $0x1, %al
movb %al, -0x2d(%rbp)
jmp 0xa7f4
movq -0x50(%rbp), %rax
movq -0x10(%rbp), %rcx
movq (%rcx), %rdx
movq %rdx, 0x1a0(%rax)
movq 0x8(%rcx), %rdx
movq %rdx, 0x1a8(%rax)
movq 0x10(%rcx), %rdx
movq %rdx, 0x1b0(%rax)
movq 0x18(%rcx), %rcx
movq %rcx, 0x1b8(%rax)
movb $0x0, -0x2e(%rbp)
movzbl -0x2e(%rbp), %eax
movq -0x10(%rbp), %rdx
movl $0x20, %ecx
subq 0x20(%rdx), %rcx
cmpq %rcx, %rax
jae 0xa8a4
movq -0x50(%rbp), %rax
movq -0x18(%rbp), %rcx
movzbl -0x2e(%rbp), %edx
movzbl (%rcx,%rdx), %esi
movzbl -0x2e(%rbp), %ecx
movq -0x10(%rbp), %rdx
addq 0x20(%rdx), %rcx
movzbl 0x1a0(%rax,%rcx), %edx
addl %esi, %edx
movb %dl, 0x1a0(%rax,%rcx)
movb -0x2e(%rbp), %al
addb $0x1, %al
movb %al, -0x2e(%rbp)
jmp 0xa857
jmp 0xa965
movb $0x0, -0x2f(%rbp)
movzbl -0x2f(%rbp), %eax
movq -0x10(%rbp), %rdx
xorl %ecx, %ecx
subq 0x20(%rdx), %rcx
cmpq %rcx, %rax
jge 0xa8e2
movq -0x18(%rbp), %rax
movzbl -0x2f(%rbp), %ecx
movzbl (%rax,%rcx), %eax
cmpl $0x0, %eax
je 0xa8d6
jmp 0xaa31
jmp 0xa8d8
movb -0x2f(%rbp), %al
addb $0x1, %al
movb %al, -0x2f(%rbp)
jmp 0xa8ad
movq -0x50(%rbp), %rax
movq -0x10(%rbp), %rcx
movq (%rcx), %rdx
movq %rdx, 0x1a0(%rax)
movq 0x8(%rcx), %rdx
movq %rdx, 0x1a8(%rax)
movq 0x10(%rcx), %rdx
movq %rdx, 0x1b0(%rax)
movq 0x18(%rcx), %rcx
movq %rcx, 0x1b8(%rax)
movq -0x10(%rbp), %rcx
xorl %eax, %eax
subq 0x20(%rcx), %rax
movb %al, -0x30(%rbp)
movzbl -0x30(%rbp), %eax
cmpq $0x20, %rax
jae 0xa963
movq -0x50(%rbp), %rax
movq -0x18(%rbp), %rcx
movzbl -0x30(%rbp), %edx
movzbl (%rcx,%rdx), %esi
movzbl -0x30(%rbp), %ecx
movq -0x10(%rbp), %rdx
addq 0x20(%rdx), %rcx
movzbl 0x1a0(%rax,%rcx), %edx
addl %esi, %edx
movb %dl, 0x1a0(%rax,%rcx)
movb -0x30(%rbp), %al
addb $0x1, %al
movb %al, -0x30(%rbp)
jmp 0xa922
jmp 0xa965
movq -0x50(%rbp), %rdi
addq $0x1d8, %rdi            # imm = 0x1D8
movq -0x20(%rbp), %rsi
movl -0x2c(%rbp), %eax
movl %eax, %edx
callq 0x3200
movq -0x50(%rbp), %rdi
addq $0x1d8, %rdi            # imm = 0x1D8
movl -0x2c(%rbp), %eax
addq %rax, %rdi
movq -0x28(%rbp), %rsi
movl 0x10(%rbp), %eax
movl %eax, %edx
callq 0x3200
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x10(%rbp), %rcx
addq 0x20(%rcx), %rax
movq %rax, -0x38(%rbp)
leaq -0x38(%rbp), %rsi
callq 0xb570
movq %rax, %rcx
movq -0x50(%rbp), %rax
movq %rcx, 0x1c8(%rax)
movq -0x10(%rbp), %rdi
addq $0x30, %rdi
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rax
movq -0x10(%rbp), %rcx
addq 0x20(%rcx), %rax
movq %rax, -0x40(%rbp)
leaq -0x40(%rbp), %rsi
callq 0xb5b0
movq %rax, %rcx
movq -0x50(%rbp), %rax
movq %rcx, 0x1d0(%rax)
cmpq $0x2710, 0x1c8(%rax) # imm = 0x2710
jg 0xaa21
movq -0x50(%rbp), %rax
cmpq $0x2710, 0x1d0(%rax) # imm = 0x2710
jle 0xaa28
movl $0x0, -0x44(%rbp)
movq -0x50(%rbp), %rdi
callq 0x77d0
addq $0x50, %rsp
popq %rbp
retq
nopw (%rax,%rax)