// File: /workspace/github_c_makefile_star2_O3/LemonBoy[P]autobahn/xdiff/xhistogram.c
// Function: histogram_diff
static int histogram_diff(xpparam_t const *xpp, xdfenv_t *env,
	int line1, int count1, int line2, int count2)
{
	struct histindex index;
	struct region lcs;
	int sz;
	int result = -1;

	if (count1 <= 0 && count2 <= 0)
		return 0;

	if (LINE_END(1) >= MAX_PTR)
		return -1;

	if (!count1) {
		while(count2--)
			env->xdf2.rchg[line2++ - 1] = 1;
		return 0;
	} else if (!count2) {
		while(count1--)
			env->xdf1.rchg[line1++ - 1] = 1;
		return 0;
	}

	memset(&index, 0, sizeof(index));

	index.env = env;
	index.xpp = xpp;

	index.records = NULL;
	index.line_map = NULL;
	/* in case of early xdl_cha_free() */
	index.rcha.head = NULL;

	index.table_bits = xdl_hashbits(count1);
	sz = index.records_size = 1 << index.table_bits;
	sz *= sizeof(struct record *);
	if (!(index.records = (struct record **) xdl_malloc(sz)))
		goto cleanup;
	memset(index.records, 0, sz);

	sz = index.line_map_size = count1;
	sz *= sizeof(struct record *);
	if (!(index.line_map = (struct record **) xdl_malloc(sz)))
		goto cleanup;
	memset(index.line_map, 0, sz);

	sz = index.line_map_size;
	sz *= sizeof(unsigned int);
	if (!(index.next_ptrs = (unsigned int *) xdl_malloc(sz)))
		goto cleanup;
	memset(index.next_ptrs, 0, sz);

	/* lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() */
	if (xdl_cha_init(&index.rcha, sizeof(struct record), count1 / 4 + 1) < 0)
		goto cleanup;

	index.ptr_shift = line1;
	index.max_chain_length = 64;

	memset(&lcs, 0, sizeof(lcs));
	if (find_lcs(&index, &lcs, line1, count1, line2, count2))
		result = fall_back_to_classic_diff(&index, line1, count1, line2, count2);
	else {
		if (lcs.begin1 == 0 && lcs.begin2 == 0) {
			while (count1--)
				env->xdf1.rchg[line1++ - 1] = 1;
			while (count2--)
				env->xdf2.rchg[line2++ - 1] = 1;
			result = 0;
		} else {
			result = histogram_diff(xpp, env,
						line1, lcs.begin1 - line1,
						line2, lcs.begin2 - line2);
			if (result)
				goto cleanup;
			result = histogram_diff(xpp, env,
						lcs.end1 + 1, LINE_END(1) - lcs.end1,
						lcs.end2 + 1, LINE_END(2) - lcs.end2);
			if (result)
				goto cleanup;
		}
	}

cleanup:
	xdl_free(index.records);
	xdl_free(index.line_map);
	xdl_free(index.next_ptrs);
	xdl_cha_free(&index.rcha);

	return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movl %ecx, %r12d
testl %ecx, %ecx
setle %al
testl %r9d, %r9d
setle %cl
xorl %r14d, %r14d
testb %cl, %al
jne 0x60b0
movl %edx, %r13d
movl %r12d, %r15d
addl %edx, %r15d
je 0x5fdc
movl %r9d, %ebp
movq %rsi, %rbx
testl %r12d, %r12d
je 0x5fe7
testl %ebp, %ebp
je 0x600a
movl %r8d, 0x4(%rsp)
xorps %xmm0, %xmm0
leaq 0x38(%rsp), %r14
movups %xmm0, 0x48(%r14)
movups %xmm0, 0x38(%r14)
movups %xmm0, 0x28(%r14)
movups %xmm0, 0x18(%r14)
movups %xmm0, 0x8(%r14)
movq $0x0, 0x58(%r14)
movq %rbx, 0x60(%r14)
movq %rdi, 0x8(%rsp)
movq %rdi, 0x68(%r14)
movups %xmm0, -0x8(%r14)
movl %r12d, %edi
callq 0x4715
movl %eax, %ecx
movl $0x1, %eax
shll %cl, %eax
movl %ecx, 0x40(%r14)
movl %eax, 0x44(%r14)
movl $0x8, %eax
shll %cl, %eax
movslq %eax, %rsi
movl $0x1, %edi
callq 0x10b0
movq %rax, -0x10(%r14)
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
testq %rax, %rax
je 0x6088
movl %r12d, 0x80(%rsp)
leal (,%r12,8), %eax
movslq %eax, %rsi
movl $0x1, %edi
callq 0x10b0
movq %rax, 0x30(%rsp)
testq %rax, %rax
je 0x6088
leal (,%r12,4), %eax
movslq %eax, %rsi
movl $0x1, %edi
callq 0x10b0
movq %rax, 0x70(%rsp)
testq %rax, %rax
je 0x6088
leal 0x3(%r12), %eax
testl %r12d, %r12d
cmovnsl %r12d, %eax
sarl $0x2, %eax
incl %eax
movslq %eax, %rdx
movl $0x10, %esi
leaq 0x38(%rsp), %rdi
callq 0x41c6
testl %eax, %eax
js 0x6088
leaq 0x28(%rsp), %rdi
movl %r13d, 0x64(%rdi)
movl $0x40, 0x5c(%rdi)
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %rsi
movaps %xmm0, (%rsi)
movl %r13d, %edx
movl %r12d, %ecx
movl 0x4(%rsp), %r14d
movl %r14d, %r8d
movl %ebp, %r9d
callq 0x60f9
testl %eax, %eax
je 0x6023
movq 0x98(%rsp), %rdi
movq 0xa0(%rsp), %rax
movq (%rax), %rax
andq $-0x61, %rax
leaq 0x20(%rsp), %rsi
movq %rax, (%rsi)
movl %r13d, %edx
movl %r12d, %ecx
movl %r14d, %r8d
movl %ebp, %r9d
callq 0x4918
movl %eax, %r14d
jmp 0x6088
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
jmp 0x60b0
testl %ebp, %ebp
je 0x60b0
movslq %r8d, %rax
movq 0xf0(%rbx), %rcx
movb $0x1, -0x1(%rcx,%rax)
incq %rax
decl %ebp
jne 0x5ff2
jmp 0x60b0
movslq %r13d, %rax
movq 0x68(%rbx), %rcx
movb $0x1, -0x1(%rcx,%rax)
incq %rax
decl %r12d
jne 0x600d
jmp 0x60b0
movl 0x10(%rsp), %ecx
movl 0x18(%rsp), %r9d
movl %ecx, %eax
orl %r9d, %eax
jne 0x6066
movslq %r13d, %rax
movl 0x4(%rsp), %edx
movq 0x68(%rbx), %rcx
movb $0x1, -0x1(%rcx,%rax)
incq %rax
decl %r12d
jne 0x603a
movslq %edx, %rax
xorl %r14d, %r14d
movq 0xf0(%rbx), %rcx
movb $0x1, -0x1(%rcx,%rax)
incq %rax
decl %ebp
jne 0x6051
jmp 0x6088
subl %r13d, %ecx
movl 0x4(%rsp), %r8d
subl %r8d, %r9d
movq 0x8(%rsp), %rdi
movq %rbx, %rsi
movl %r13d, %edx
callq 0x5e26
movl %eax, %r14d
testl %eax, %eax
je 0x60c5
movq 0x28(%rsp), %rdi
callq 0x1030
movq 0x30(%rsp), %rdi
callq 0x1030
movq 0x70(%rsp), %rdi
callq 0x1030
leaq 0x38(%rsp), %rdi
callq 0x41e7
movl %r14d, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl 0x14(%rsp), %eax
movl 0x1c(%rsp), %r9d
leal 0x1(%rax), %edx
notl %eax
addl %eax, %r15d
leal 0x1(%r9), %r8d
addl 0x4(%rsp), %ebp
notl %r9d
addl %ebp, %r9d
movq 0x8(%rsp), %rdi
movq %rbx, %rsi
movl %r15d, %ecx
callq 0x5e26
jmp 0x5fd4