// File: /workspace/github_c_makefile_star2_O2/lmcilroy[P]lzm/lzmencode.c
// Function: matchlen_rev
static inline int
matchlen_rev(const unsigned char * const start, const unsigned char * const match,
    const unsigned char * const start_limit, const unsigned char * const match_limit)
{
	const unsigned char *curr = start;
	const unsigned char *last = match;
	const unsigned char *next_curr;
	const unsigned char *next_last;
	const unsigned char *end;
	unsigned long currval, lastval;
	unsigned int off;

	if (start == start_limit)
		return 0;

	if (match == match_limit)
		return 0;

	if (*(start-1) != *(match-1))
		return 0;

	end = match_limit;
	off = start - start_limit;
	if (off < (match - match_limit))
		end = match - off;

	if (last > (end + 7)) {
		next_curr = curr - 8;
		next_last = last - 8;
		currval = readmem64(next_curr);
		lastval = readmem64(next_last);
		if (currval != lastval)
			return (__builtin_clzl(currval ^ lastval) >> 3);
		curr = next_curr;
		last = next_last;
	}
	while (last > (end + 7)) {
		next_curr = curr - 8;
		next_last = last - 8;
		currval = readmem64(next_curr);
		lastval = readmem64(next_last);
		if (currval != lastval) {
			off = __builtin_clzl(currval ^ lastval) >> 3;
			return (start - curr) + off;
		}
		curr = next_curr;
		last = next_last;
	}
	if (last > (end + 3)) {
		next_curr = curr - 4;
		next_last = last - 4;
		currval = readmem32(next_curr);
		lastval = readmem32(next_last);
		if (currval != lastval) {
			off = __builtin_clz(currval ^ lastval) >> 3;
			return (start - curr) + off;
		}
		curr = next_curr;
		last = next_last;
	}
	if (last > (end + 1)) {
		next_curr = curr - 2;
		next_last = last - 2;
		currval = readmem16(next_curr);
		lastval = readmem16(next_last);
		if (readmem16(next_curr) == readmem16(next_last)) {
			curr = next_curr;
			last = next_last;
		}
	}
	if (last > end) {
		next_curr = curr - 1;
		next_last = last - 1;
		if (*next_curr == *next_last) {
			curr = next_curr;
			last = next_last;
		}
	}

	return start - curr;
}

// Assembly:
cmpq %rdx, %rdi
sete %r9b
movq %rsi, %r8
subq %rcx, %r8
sete %r10b
xorl %eax, %eax
orb %r9b, %r10b
jne 0x3c93
movb -0x1(%rdi), %r9b
cmpb -0x1(%rsi), %r9b
jne 0x3c93
movl %edi, %eax
subl %edx, %eax
movq %rsi, %rdx
subq %rax, %rdx
cmpq %r8, %rax
cmovlq %rdx, %rcx
leaq 0x7(%rcx), %r9
cmpq %rsi, %r9
jae 0x3c21
movq -0x8(%rdi), %rax
movq -0x8(%rsi), %rdx
cmpq %rdx, %rax
jne 0x3c86
leaq -0x8(%rdi), %rax
addq $-0x8, %rsi
jmp 0x3c24
movq %rdi, %rax
xorl %edx, %edx
leaq (%rsi,%rdx), %r8
cmpq %r9, %r8
jbe 0x3c5d
movq -0x8(%rax,%rdx), %r8
movq -0x8(%rsi,%rdx), %r10
addq $-0x8, %rdx
cmpq %r10, %r8
je 0x3c26
xorq %r8, %r10
bsrq %r10, %rcx
xorl $0x38, %ecx
shrl $0x3, %ecx
subl %eax, %edi
addl %ecx, %edi
subl %edx, %edi
addl $-0x8, %edi
jmp 0x3ce5
leaq 0x3(%rcx), %r9
cmpq %r9, %r8
jbe 0x3c94
movl -0x4(%rax,%rdx), %r8d
movl -0x4(%rsi,%rdx), %r9d
cmpl %r9d, %r8d
jne 0x3cd2
addq %rdx, %rax
addq $-0x4, %rax
leaq (%rsi,%rdx), %r8
addq $-0x4, %r8
jmp 0x3c97
xorq %rax, %rdx
bsrq %rdx, %rax
xorl $0x38, %eax
shrl $0x3, %eax
retq
addq %rdx, %rax
leaq 0x1(%rcx), %rdx
cmpq %rdx, %r8
jbe 0x3cba
leaq -0x2(%rax), %rdx
leaq -0x2(%r8), %rsi
movzwl -0x2(%rax), %r9d
cmpw -0x2(%r8), %r9w
cmoveq %rdx, %rax
cmoveq %rsi, %r8
cmpq %rcx, %r8
jbe 0x3cce
leaq -0x1(%rax), %rcx
movb -0x1(%rax), %dl
cmpb -0x1(%r8), %dl
cmoveq %rcx, %rax
subl %eax, %edi
jmp 0x3ce5
xorl %r8d, %r9d
bsrl %r9d, %ecx
xorl $0x18, %ecx
shrl $0x3, %ecx
subl %eax, %edi
addl %ecx, %edi
subl %edx, %edi
movl %edi, %eax
retq