// File: /workspace/github_c_makefile_star2_O0/DavidSM64[P]DKR-Decompressor/DKRGzip.c
// Function: longest_match(unsigned int)
int longest_match(IPos cur_match) {
    unsigned chain_length = max_chain_length;   /* max hash chain length */
    u8 *scan = window + strstart;     /* current string */
    u8 *match;                        /* matched string */
    int len;                           /* length of current match */
    int best_len = prev_length;                 /* best match length so far */
    IPos limit = strstart > (IPos)MAX_DIST ? strstart - (IPos)MAX_DIST : NIL;
    /* Stop when cur_match becomes <= limit. To simplify the code,
     * we prevent matches with the string of window index 0.
     */

#ifdef UNALIGNED_OK
    /* Compare two bytes at a time. Note: this is not always beneficial.
     * Try with and without -DUNALIGNED_OK to check.
     */
    u8 *strend = window + strstart + MAX_MATCH - 1;
    u16 scan_start = *(u16*)scan;
    u16 scan_end   = *(u16*)(scan+best_len-1);
#else
    u8 *strend = window + strstart + MAX_MATCH;
    u8 scan_end1  = scan[best_len-1];
    u8 scan_end   = scan[best_len];
#endif

    /* Do not waste too mu8 time if we already have a good match: */
    if (prev_length >= good_match) {
        chain_length >>= 2;
    }
    //Assert(strstart <= window_size-MIN_LOOKAHEAD, "insufficient lookahead");

    do {
        //Assert(cur_match < strstart, "no future");
        match = window + cur_match;

        /* Skip to next match if the match length cannot increase
         * or if the match length is less than 2:
         */
#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
        /* This code assumes sizeof(unsigned short) == 2. Do not use
         * UNALIGNED_OK if your compiler uses a different size.
         */
        if (*(u16*)(match+best_len-1) != scan_end ||
            *(u16*)match != scan_start) continue;

        /* It is not necessary to compare scan[2] and match[2] since they are
         * always equal when the other bytes match, given that the hash keys
         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
         * strstart+3, +5, ... up to strstart+257. We check for insufficient
         * lookahead only every 4th comparison; the 128th check will be made
         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
         * necessary to put more guard bytes at the end of the window, or
         * to check more often for insufficient lookahead.
         */
        scan++, match++;
        do {
        } while (*(u16*)(scan+=2) == *(u16*)(match+=2) &&
                 *(u16*)(scan+=2) == *(u16*)(match+=2) &&
                 *(u16*)(scan+=2) == *(u16*)(match+=2) &&
                 *(u16*)(scan+=2) == *(u16*)(match+=2) &&
                 scan < strend);
        /* The funny "do {}" generates better code on most compilers */

        /* Here, scan <= window+strstart+257 */
        //Assert(scan <= window+(unsigned)(window_size-1), "wild scan");
        if (*scan == *match) scan++;

        len = (MAX_MATCH - 1) - (int)(strend-scan);
        scan = strend - (MAX_MATCH-1);

#else /* UNALIGNED_OK */

        if (match[best_len]   != scan_end  ||
            match[best_len-1] != scan_end1 ||
            *match            != *scan     ||
            *++match          != scan[1])      continue;

        /* The check at best_len-1 can be removed because it will be made
         * again later. (This heuristic is not always a win.)
         * It is not necessary to compare scan[2] and match[2] since they
         * are always equal when the other bytes match, given that
         * the hash keys are equal and that HASH_BITS >= 8.
         */
        scan += 2, match++;

        /* We check for insufficient lookahead only every 8th comparison;
         * the 256th check will be made at strstart+258.
         */
        do {
        } while (*++scan == *++match && *++scan == *++match &&
                 *++scan == *++match && *++scan == *++match &&
                 *++scan == *++match && *++scan == *++match &&
                 *++scan == *++match && *++scan == *++match &&
                 scan < strend);

        len = MAX_MATCH - (int)(strend - scan);
        scan = strend - MAX_MATCH;

#endif /* UNALIGNED_OK */

        if (len > best_len) {
            match_start = cur_match;
            best_len = len;
            if (len >= nice_match) break;
#ifdef UNALIGNED_OK
            scan_end = *(u16*)(scan+best_len-1);
#else
            scan_end1  = scan[best_len-1];
            scan_end   = scan[best_len];
#endif
        }
    } while ((cur_match = prev[cur_match & WMASK]) > limit
	     && --chain_length != 0);

    return best_len;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movl %edi, -0x4(%rbp)
movl 0x80db(%rip), %eax      # 0x10c18
movl %eax, -0x8(%rbp)
movl 0x80c6(%rip), %eax      # 0x10c0c
movl %eax, %ecx
leaq 0x100b051(%rip), %rax   # 0x1013ba0
addq %rcx, %rax
movq %rax, -0x10(%rbp)
movl 0x80ac(%rip), %eax      # 0x10c08
movl %eax, -0x20(%rbp)
cmpl $0x7efa, 0x80a3(%rip)   # imm = 0x7EFA
jbe 0x8b7b
movl 0x809b(%rip), %eax      # 0x10c0c
subl $0x7efa, %eax           # imm = 0x7EFA
movl %eax, -0x38(%rbp)
jmp 0x8b82
xorl %eax, %eax
movl %eax, -0x38(%rbp)
jmp 0x8b82
movl -0x38(%rbp), %eax
movl %eax, -0x24(%rbp)
movl 0x807e(%rip), %eax      # 0x10c0c
movl %eax, %ecx
leaq 0x100b009(%rip), %rax   # 0x1013ba0
addq %rcx, %rax
addq $0x102, %rax            # imm = 0x102
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movl -0x20(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movb (%rax,%rcx), %al
movb %al, -0x31(%rbp)
movq -0x10(%rbp), %rax
movslq -0x20(%rbp), %rcx
movb (%rax,%rcx), %al
movb %al, -0x32(%rbp)
movl 0x803d(%rip), %eax      # 0x10c08
cmpl 0x8053(%rip), %eax      # 0x10c24
jb 0x8bdc
movl -0x8(%rbp), %eax
shrl $0x2, %eax
movl %eax, -0x8(%rbp)
jmp 0x8bde
movl -0x4(%rbp), %eax
movl %eax, %ecx
leaq 0x100afb6(%rip), %rax   # 0x1013ba0
addq %rcx, %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movslq -0x20(%rbp), %rcx
movzbl (%rax,%rcx), %eax
movzbl -0x32(%rbp), %ecx
cmpl %ecx, %eax
jne 0x8c4f
movq -0x18(%rbp), %rax
movl -0x20(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %eax
movzbl -0x31(%rbp), %ecx
cmpl %ecx, %eax
jne 0x8c4f
movq -0x18(%rbp), %rax
movzbl (%rax), %eax
movq -0x10(%rbp), %rcx
movzbl (%rcx), %ecx
cmpl %ecx, %eax
jne 0x8c4f
movq -0x18(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x18(%rbp)
movzbl 0x1(%rax), %eax
movq -0x10(%rbp), %rcx
movzbl 0x1(%rcx), %ecx
cmpl %ecx, %eax
je 0x8c54
jmp 0x8e7f
movq -0x10(%rbp), %rax
addq $0x2, %rax
movq %rax, -0x10(%rbp)
movq -0x18(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x18(%rbp)
jmp 0x8c6e
movq -0x10(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x10(%rbp)
movzbl 0x1(%rax), %ecx
movq -0x18(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x18(%rbp)
movzbl 0x1(%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x39(%rbp)
jne 0x8e08
movq -0x10(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x10(%rbp)
movzbl 0x1(%rax), %ecx
movq -0x18(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x18(%rbp)
movzbl 0x1(%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x39(%rbp)
jne 0x8e08
movq -0x10(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x10(%rbp)
movzbl 0x1(%rax), %ecx
movq -0x18(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x18(%rbp)
movzbl 0x1(%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x39(%rbp)
jne 0x8e08
movq -0x10(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x10(%rbp)
movzbl 0x1(%rax), %ecx
movq -0x18(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x18(%rbp)
movzbl 0x1(%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x39(%rbp)
jne 0x8e08
movq -0x10(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x10(%rbp)
movzbl 0x1(%rax), %ecx
movq -0x18(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x18(%rbp)
movzbl 0x1(%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x39(%rbp)
jne 0x8e08
movq -0x10(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x10(%rbp)
movzbl 0x1(%rax), %ecx
movq -0x18(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x18(%rbp)
movzbl 0x1(%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x39(%rbp)
jne 0x8e08
movq -0x10(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x10(%rbp)
movzbl 0x1(%rax), %ecx
movq -0x18(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x18(%rbp)
movzbl 0x1(%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x39(%rbp)
jne 0x8e08
movq -0x10(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x10(%rbp)
movzbl 0x1(%rax), %ecx
movq -0x18(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x18(%rbp)
movzbl 0x1(%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x39(%rbp)
jne 0x8e08
movq -0x10(%rbp), %rax
cmpq -0x30(%rbp), %rax
setb %al
movb %al, -0x39(%rbp)
movb -0x39(%rbp), %al
testb $0x1, %al
jne 0x8c6c
movq -0x30(%rbp), %rax
movq -0x10(%rbp), %rcx
subq %rcx, %rax
movl %eax, %ecx
movl $0x102, %eax            # imm = 0x102
subl %ecx, %eax
movl %eax, -0x1c(%rbp)
movq -0x30(%rbp), %rax
addq $-0x102, %rax           # imm = 0xFEFE
movq %rax, -0x10(%rbp)
movl -0x1c(%rbp), %eax
cmpl -0x20(%rbp), %eax
jle 0x8e7d
movl -0x4(%rbp), %eax
movl %eax, 0x7dc7(%rip)      # 0x10c10
movl -0x1c(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x1c(%rbp), %eax
cmpl 0x7dd8(%rip), %eax      # 0x10c30
jl 0x8e5c
jmp 0x8ec0
movq -0x10(%rbp), %rax
movl -0x20(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movb (%rax,%rcx), %al
movb %al, -0x31(%rbp)
movq -0x10(%rbp), %rax
movslq -0x20(%rbp), %rcx
movb (%rax,%rcx), %al
movb %al, -0x32(%rbp)
jmp 0x8e7f
movl -0x4(%rbp), %eax
andl $0x7fff, %eax           # imm = 0x7FFF
movl %eax, %eax
movl %eax, %ecx
leaq 0x101ad0e(%rip), %rax   # 0x1023ba0
movzwl (%rax,%rcx,2), %ecx
movl %ecx, -0x4(%rbp)
xorl %eax, %eax
cmpl -0x24(%rbp), %ecx
movb %al, -0x3a(%rbp)
jbe 0x8eb5
movl -0x8(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x8(%rbp)
cmpl $0x0, %eax
setne %al
movb %al, -0x3a(%rbp)
movb -0x3a(%rbp), %al
testb $0x1, %al
jne 0x8bde
movl -0x20(%rbp), %eax
popq %rbp
retq
nopw %cs:(%rax,%rax)