// File: /workspace/github_c_makefile_star2_O1/DavidSM64[P]DKR-Decompressor/DKRGzip.c
// Function: deflate()
void deflate() {
    IPos hash_head;          /* head of hash chain */
    IPos prev_match;         /* previous match */
    int flush;               /* set if current block must be flushed */
    int match_available = 0; /* set if previous match exists */
    u32 match_length = MIN_MATCH-1; /* length of best match */

    /*
    if (compr_level <= 3){ 
        deflate_fast();
        return;
    }
    */
    
    /* Process the input block. */
    while (lookahead != 0) {
        
        /* Insert the string window[strstart .. strstart+2] in the
         * dictionary, and set hash_head to the head of the hash chain:
         */
        INSERT_STRING(strstart, hash_head);

        /* Find the longest match, discarding those <= prev_length.
         */
        prev_length = match_length, prev_match = match_start;
        match_length = MIN_MATCH-1;
        
        if (hash_head != NIL && prev_length < max_lazy_match &&
            strstart - hash_head <= MAX_DIST &&
	    strstart <= window_size - MIN_LOOKAHEAD) {
            /* To simplify the code, we prevent matches with the string
             * of window index 0 (in particular we have to avoid a match
             * of the string with itself at the start of the input file).
             */
             
            match_length = longest_match (hash_head);
            
            /* longest_match() sets match_start */
            if (match_length > lookahead) match_length = lookahead;

            /* Ignore a length 3 match if it is too distant: */
            if (match_length == MIN_MATCH && strstart-match_start > TOO_FAR){
                /* If prev_match is also MIN_MATCH, match_start is garbage
                 * but we will ignore the current match anyway.
                 */
                match_length--;
            }
        }
        
        /* If there was a match at the previous step and the current
         * match is not better, output the previous match:
         */
        if (prev_length >= MIN_MATCH && match_length <= prev_length) {

            flush = ct_tally(strstart-1-prev_match, prev_length - MIN_MATCH);
            
            /* Insert in hash table all strings up to the end of the match.
             * strstart-1 and strstart are already inserted.
             */
            lookahead -= prev_length-1;
            prev_length -= 2;
            RSYNC_ROLL(strstart, prev_length+1);
            do {
                strstart++;
                INSERT_STRING(strstart, hash_head);
                /* strstart never exceeds WSIZE-MAX_MATCH, so there are
                 * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
                 * these bytes are garbage, but it does not matter since the
                 * next lookahead bytes will always be emitted as literals.
                 */
            } while (--prev_length != 0);
            match_available = 0;
            match_length = MIN_MATCH-1;
            strstart++;

            if (rsync && strstart > rsync_chunk_end) {
                rsync_chunk_end = 0xFFFFFFFF;
                flush = 2;
            }
            if (flush) FLUSH_BLOCK(0), block_start = strstart;
        } else if (match_available) {
            /* If there was no match at the previous position, output a
             * single literal. If there was a match but the current match
             * is longer, truncate the previous match to a single literal.
             */
            //Tracevv((stderr,"%c",window[strstart-1]));
            
            flush = ct_tally (0, window[strstart-1]);
            if (rsync && strstart > rsync_chunk_end) {
                rsync_chunk_end = 0xFFFFFFFF;
                flush = 2;
            }
            if (flush) FLUSH_BLOCK(0), block_start = strstart;
            RSYNC_ROLL(strstart, 1);
            strstart++;
            lookahead--;
        } else {
        
            /* There is no previous match to compare with, wait for
             * the next step to decide.
             */
            if (rsync && strstart > rsync_chunk_end) {
                /* Reset huffman tree */
                rsync_chunk_end = 0xFFFFFFFF;
                flush = 2;
                FLUSH_BLOCK(0), block_start = strstart;
            }
            match_available = 1;
            RSYNC_ROLL(strstart, 1);
            strstart++;
            lookahead--;
        }
        // Assert (strstart <= bytes_in && lookahead <= bytes_in, "a bit too far");

        /* Make sure that we always have enough lookahead, except
         * at the end of the input file. We need MAX_MATCH bytes
         * for the next match, plus MIN_MATCH bytes to insert the
         * string following the next match.
         */
        
        while (lookahead < MIN_LOOKAHEAD && !NO_MORE_INPUT) { 
            fill_window();
        }
    }
    if (match_available) {
        ct_tally (0, window[strstart-1]);
    }

    FLUSH_BLOCK(1);
    return;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
cmpl $0x0, 0x4aea(%rip)      # 0xabb4
je 0x6407
movl $0x0, -0x30(%rbp)
movl $0x2, %r13d
leaq 0x1007a5c(%rip), %r15   # 0x100db40
leaq 0x1017a55(%rip), %r12   # 0x101db40
movq %r14, -0x38(%rbp)
movl 0x4aaf(%rip), %edx      # 0xaba4
shll $0x5, %edx
movl 0x4aae(%rip), %eax      # 0xabac
leal 0x2(%rax), %ecx
movzbl (%rcx,%r15), %ecx
andl $0x7fe0, %edx           # imm = 0x7FE0
xorl %ecx, %edx
movl %edx, 0x4a90(%rip)      # 0xaba4
movzwl 0x10000(%r12,%rdx,2), %ecx
movzwl %cx, %edi
movl %eax, %esi
andl $0x7fff, %esi           # imm = 0x7FFF
movw %di, (%r12,%rsi,2)
movw %ax, 0x10000(%r12,%rdx,2)
movl %r13d, 0x4a6b(%rip)     # 0xaba8
movl 0x4a6c(%rip), %r14d     # 0xabb0
movl %eax, %edx
subl %edi, %edx
movl $0x2, %ebx
cmpl $0x7efa, %edx           # imm = 0x7EFA
ja 0x61a2
testw %cx, %cx
je 0x61a2
cmpl 0x4a5b(%rip), %r13d     # 0xabbc
jae 0x61a2
movl 0x4277(%rip), %ecx      # 0xa3e0
movl $0xfffffefa, %edx       # imm = 0xFFFFFEFA
addl %edx, %ecx
cmpl %ecx, %eax
ja 0x61a2
callq 0x4d97
movl 0x4a35(%rip), %ebx      # 0xabb4
cmpl %ebx, %eax
cmovbl %eax, %ebx
cmpl $0x3, %ebx
jne 0x61a2
movl 0x4a1d(%rip), %eax      # 0xabac
subl 0x4a1b(%rip), %eax      # 0xabb0
cmpl $0x1001, %eax           # imm = 0x1001
movl $0x0, %ebx
adcl $0x2, %ebx
movl 0x4a00(%rip), %esi      # 0xaba8
cmpl $0x3, %esi
setae %al
cmpl %esi, %ebx
setbe %cl
andb %al, %cl
movb %cl, -0x29(%rbp)
cmpb $0x1, %cl
jne 0x62c4
notl %r14d
addl 0x49e1(%rip), %r14d     # 0xabac
addl $-0x3, %esi
movl %r14d, %edi
callq 0x5d75
movl %eax, %r14d
movl 0x49c9(%rip), %eax      # 0xaba8
leal -0x1(%rax), %esi
subl %esi, 0x49cc(%rip)      # 0xabb4
addl $-0x2, %eax
movl %eax, 0x49b7(%rip)      # 0xaba8
cmpl $0x0, 0x1047948(%rip)   # 0x104db40
je 0x6205
movl 0x49ac(%rip), %edi      # 0xabac
callq 0x5fe7
movl 0x49a1(%rip), %esi      # 0xabac
movl 0x4993(%rip), %eax      # 0xaba4
movl 0x4991(%rip), %ecx      # 0xaba8
incl %esi
shll $0x5, %eax
leal 0x2(%rsi), %edx
movzbl (%rdx,%r15), %edx
andl $0x7fe0, %eax           # imm = 0x7FE0
xorl %edx, %eax
movzwl 0x10000(%r12,%rax,2), %edx
movl %esi, %edi
andl $0x7fff, %edi           # imm = 0x7FFF
movw %dx, (%r12,%rdi,2)
movw %si, 0x10000(%r12,%rax,2)
incl %esi
decl %ecx
jne 0x6219
movl %eax, 0x494e(%rip)      # 0xaba4
movl $0x0, 0x4948(%rip)      # 0xaba8
movl %esi, 0x4946(%rip)      # 0xabac
cmpl $0x0, 0x10478d3(%rip)   # 0x104db40
je 0x6287
cmpl 0x4957(%rip), %esi      # 0xabcc
jbe 0x6287
movl $0xffffffff, 0x494b(%rip) # imm = 0xFFFFFFFF
movl $0x2, %r14d
movl $0x2, %r13d
testl %r14d, %r14d
je 0x633f
movl 0x4904(%rip), %edi      # 0xaba0
subl %edi, %esi
addq %r15, %rdi
leal -0x1(%r14), %edx
movl $0x0, -0x30(%rbp)
xorl %ecx, %ecx
callq 0x5bbb
movl 0x48f3(%rip), %eax      # 0xabac
movl %eax, 0x48e1(%rip)      # 0xaba0
jmp 0x63d1
cmpl $0x0, -0x30(%rbp)
je 0x634e
movl 0x48d8(%rip), %eax      # 0xabac
decl %eax
movzbl (%rax,%r15), %esi
xorl %edi, %edi
callq 0x5d75
movl %eax, %r14d
cmpl $0x0, 0x1047854(%rip)   # 0x104db40
je 0x630c
movl 0x48b8(%rip), %eax      # 0xabac
cmpl 0x48d2(%rip), %eax      # 0xabcc
jbe 0x630c
movl $0xffffffff, 0x48c6(%rip) # imm = 0xFFFFFFFF
movl $0x2, %r14d
testl %r14d, %r14d
je 0x63a2
movl 0x4885(%rip), %edi      # 0xaba0
movl 0x488b(%rip), %esi      # 0xabac
subl %edi, %esi
addq %r15, %rdi
leal -0x1(%r14), %edx
xorl %ecx, %ecx
callq 0x5bbb
movl 0x4875(%rip), %eax      # 0xabac
movl %eax, 0x4863(%rip)      # 0xaba0
jmp 0x63a2
xorl %r14d, %r14d
movl $0x0, -0x30(%rbp)
jmp 0x63d1
cmpl $0x0, 0x10477eb(%rip)   # 0x104db40
je 0x639e
movl 0x484f(%rip), %esi      # 0xabac
cmpl 0x4869(%rip), %esi      # 0xabcc
movq -0x38(%rbp), %r14
jbe 0x63a2
movl $0xffffffff, 0x4859(%rip) # imm = 0xFFFFFFFF
movl 0x4827(%rip), %edi      # 0xaba0
subl %edi, %esi
addq %r15, %rdi
movl $0x1, %edx
xorl %ecx, %ecx
callq 0x5bbb
movl 0x481c(%rip), %eax      # 0xabac
movl %eax, 0x480a(%rip)      # 0xaba0
movl $0x2, %r14d
jmp 0x63a2
movq -0x38(%rbp), %r14
cmpl $0x0, 0x1047797(%rip)   # 0x104db40
je 0x63bb
movl 0x47fb(%rip), %edi      # 0xabac
movl $0x1, %esi
callq 0x5fe7
incl 0x47eb(%rip)            # 0xabac
decl 0x47ed(%rip)            # 0xabb4
movl $0x1, -0x30(%rbp)
movl %ebx, %r13d
cmpl $0x105, 0x47d9(%rip)    # imm = 0x105
ja 0x63f2
movl 0x100773d(%rip), %eax   # 0x100db20
cmpl %eax, 0x100773b(%rip)   # 0x100db24
je 0x63f2
callq 0x5ede
jmp 0x63d1
cmpl $0x0, 0x47bb(%rip)      # 0xabb4
jne 0x60eb
decl %r14d
movb -0x29(%rbp), %al
jmp 0x6409
movb $0x1, %al
testb %al, %al
jne 0x6427
movl 0x4799(%rip), %eax      # 0xabac
decl %eax
leaq 0x1007724(%rip), %rcx   # 0x100db40
movzbl (%rax,%rcx), %esi
xorl %edi, %edi
callq 0x5d75
movl 0x4773(%rip), %eax      # 0xaba0
leaq 0x100770c(%rip), %rdi   # 0x100db40
addq %rax, %rdi
movl 0x476f(%rip), %esi      # 0xabac
subl %eax, %esi
movl %r14d, %edx
movl $0x1, %ecx
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x5bbb