// File: /workspace/github_c_makefile_star2_O1/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 $0xb8, %rsp
movl %ecx, %r12d
testl %ecx, %ecx
setle %al
testl %r9d, %r9d
setle %cl
xorl %r14d, %r14d
testb %cl, %al
jne 0x62f7
movl %edx, %r13d
movl %r12d, %eax
addl %edx, %eax
je 0x6292
movl %r9d, %ebp
movq %rsi, %rbx
testl %r12d, %r12d
je 0x629a
testl %ebp, %ebp
je 0x62e3
movl %eax, 0x4(%rsp)
movl %r8d, (%rsp)
xorps %xmm0, %xmm0
leaq 0x40(%rsp), %r14
movaps %xmm0, 0x60(%r14)
movaps %xmm0, (%r14)
movaps %xmm0, 0x50(%r14)
movaps %xmm0, 0x40(%r14)
movaps %xmm0, 0x30(%r14)
movaps %xmm0, 0x20(%r14)
movaps %xmm0, 0x10(%r14)
movaps %xmm0, -0x10(%r14)
movq %rbx, 0x60(%r14)
movq %rdi, 0x8(%rsp)
movq %rdi, 0x68(%r14)
movq $0x0, (%r14)
movl %r12d, %edi
callq 0x4939
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, %r15
movq %r15, %rdi
callq 0x10e0
movq %rax, -0x10(%r14)
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
testq %rax, %rax
je 0x62b6
movq %rax, %rdi
xorl %esi, %esi
movq %r15, %rdx
callq 0x1090
movl %r12d, 0x88(%rsp)
leal (,%r12,8), %eax
movslq %eax, %r15
movq %r15, %rdi
callq 0x10e0
movq %rax, 0x38(%rsp)
testq %rax, %rax
je 0x62b6
movq %rax, %rdi
xorl %esi, %esi
movq %r15, %rdx
callq 0x1090
leal (,%r12,4), %eax
movslq %eax, %r15
movq %r15, %rdi
callq 0x10e0
movq %rax, 0x78(%rsp)
testq %rax, %rax
je 0x62b6
movq %rax, %rdi
xorl %esi, %esi
movq %r15, %rdx
callq 0x1090
leal 0x3(%r12), %eax
testl %r12d, %r12d
cmovnsl %r12d, %eax
sarl $0x2, %eax
incl %eax
movslq %eax, %rdx
movl $0x10, %esi
leaq 0x40(%rsp), %r15
movq %r15, %rdi
callq 0x431e
testl %eax, %eax
js 0x62bb
leaq 0x30(%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 (%rsp), %r14d
movl %r14d, %r8d
movl %ebp, %r9d
callq 0x63a9
testl %eax, %eax
je 0x630c
movq 0xa0(%rsp), %rdi
movq 0xa8(%rsp), %rax
movq (%rax), %rax
andq $-0x61, %rax
leaq 0x28(%rsp), %rsi
movq %rax, (%rsi)
movl %r13d, %edx
movl %r12d, %ecx
movl %r14d, %r8d
movl %ebp, %r9d
callq 0x4b4d
movl %eax, %r14d
jmp 0x62bb
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
jmp 0x62f7
testl %ebp, %ebp
je 0x62f7
movslq %r8d, %rax
movq 0xf0(%rbx), %rcx
movb $0x1, -0x1(%rcx,%rax)
incq %rax
decl %ebp
jne 0x62a1
jmp 0x62f7
leaq 0x40(%rsp), %r15
movq 0x30(%rsp), %rdi
callq 0x1030
movq 0x38(%rsp), %rdi
callq 0x1030
movq 0x78(%rsp), %rdi
callq 0x1030
movq %r15, %rdi
callq 0x433f
jmp 0x62f7
movslq %r13d, %rax
movq 0x68(%rbx), %rcx
movb $0x1, -0x1(%rcx,%rax)
incq %rax
decl %r12d
jne 0x62e6
movl %r14d, %eax
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl 0x10(%rsp), %ecx
movl 0x18(%rsp), %r9d
movl %ecx, %eax
orl %r9d, %eax
jne 0x6351
movslq %r13d, %rax
movl (%rsp), %edx
movq 0x68(%rbx), %rcx
movb $0x1, -0x1(%rcx,%rax)
incq %rax
decl %r12d
jne 0x6322
movslq %edx, %rax
xorl %r14d, %r14d
movq 0xf0(%rbx), %rcx
movb $0x1, -0x1(%rcx,%rax)
incq %rax
decl %ebp
jne 0x6339
jmp 0x62bb
subl %r13d, %ecx
movl (%rsp), %r8d
subl %r8d, %r9d
movq 0x8(%rsp), %rdi
movq %rbx, %rsi
movl %r13d, %edx
callq 0x60ae
movl %eax, %r14d
testl %eax, %eax
jne 0x62bb
movl 0x14(%rsp), %eax
movl 0x1c(%rsp), %r9d
leal 0x1(%rax), %edx
notl %eax
movl 0x4(%rsp), %ecx
addl %eax, %ecx
leal 0x1(%r9), %r8d
addl (%rsp), %ebp
notl %r9d
addl %ebp, %r9d
movq 0x8(%rsp), %rdi
movq %rbx, %rsi
callq 0x60ae
jmp 0x628d