// File: /workspace/github_c_makefile_star2_O3/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
xorl %r15d, %r15d
movl $0x2, %r13d
leaq 0x1007b7a(%rip), %rbx   # 0x100db40
leaq 0x1017b73(%rip), %r12   # 0x101db40
movq %rax, -0x38(%rbp)
movl %r15d, -0x3c(%rbp)
movl 0x4bc9(%rip), %edx      # 0xaba4
shll $0x5, %edx
movl 0x4bc8(%rip), %eax      # 0xabac
leal 0x2(%rax), %ecx
movzbl (%rcx,%rbx), %ecx
andl $0x7fe0, %edx           # imm = 0x7FE0
xorl %ecx, %edx
movl %edx, 0x4bab(%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, 0x4b86(%rip)     # 0xaba8
movl 0x4b87(%rip), %r15d     # 0xabb0
movl %eax, %edx
subl %edi, %edx
movl $0x2, %r14d
cmpl $0x7efa, %edx           # imm = 0x7EFA
ja 0x608e
testw %cx, %cx
je 0x608e
cmpl 0x4b75(%rip), %r13d     # 0xabbc
jae 0x608e
movl 0x4391(%rip), %ecx      # 0xa3e0
movl $0xfffffefa, %edx       # imm = 0xFFFFFEFA
addl %edx, %ecx
cmpl %ecx, %eax
ja 0x608e
callq 0x4c83
movl 0x4b4e(%rip), %r14d     # 0xabb4
cmpl %r14d, %eax
cmovbl %eax, %r14d
cmpl $0x3, %r14d
jne 0x608e
movl 0x4b33(%rip), %eax      # 0xabac
subl 0x4b31(%rip), %eax      # 0xabb0
cmpl $0x1001, %eax           # imm = 0x1001
movl $0x0, %r14d
adcl $0x2, %r14d
movl 0x4b14(%rip), %esi      # 0xaba8
cmpl $0x3, %esi
setae %al
cmpl %esi, %r14d
setbe %cl
andb %al, %cl
cmpb $0x1, %cl
movb %cl, -0x29(%rbp)
jne 0x6176
notl %r15d
addl 0x4af4(%rip), %r15d     # 0xabac
addl $-0x3, %esi
movl %r15d, %edi
callq 0x5c5e
movl %eax, %r14d
movl 0x4adc(%rip), %eax      # 0xaba8
leal -0x1(%rax), %esi
subl %esi, 0x4adf(%rip)      # 0xabb4
addl $-0x2, %eax
movl %eax, 0x4aca(%rip)      # 0xaba8
cmpl $0x0, 0x1047a5b(%rip)   # 0x104db40
je 0x60f8
movl 0x4abf(%rip), %edi      # 0xabac
callq 0x5ede
movl 0x4ab0(%rip), %eax      # 0xaba8
movl 0x4aae(%rip), %esi      # 0xabac
movl 0x4aa0(%rip), %ecx      # 0xaba4
incl %esi
shll $0x5, %ecx
leal 0x2(%rsi), %edx
movzbl (%rdx,%rbx), %edx
andl $0x7fe0, %ecx           # imm = 0x7FE0
xorl %edx, %ecx
movzwl 0x10000(%r12,%rcx,2), %edx
movl %esi, %edi
andl $0x7fff, %edi           # imm = 0x7FFF
movw %dx, (%r12,%rdi,2)
movw %si, 0x10000(%r12,%rcx,2)
incl %esi
decl %eax
jne 0x6106
movl %ecx, 0x4a61(%rip)      # 0xaba4
movl $0x0, 0x4a5b(%rip)      # 0xaba8
movl %esi, 0x4a59(%rip)      # 0xabac
cmpl $0x0, 0x10479e6(%rip)   # 0x104db40
je 0x61c8
cmpl 0x4a6a(%rip), %esi      # 0xabcc
jbe 0x61c8
movl $0xffffffff, 0x4a5e(%rip) # imm = 0xFFFFFFFF
movl $0x2, %r14d
jmp 0x61d1
cmpl $0x0, -0x3c(%rbp)
je 0x6205
movl 0x4a26(%rip), %eax      # 0xabac
decl %eax
movzbl (%rax,%rbx), %esi
xorl %edi, %edi
callq 0x5c5e
movl 0x10479a7(%rip), %ecx   # 0x104db40
movl 0x4a0d(%rip), %esi      # 0xabac
testl %ecx, %ecx
je 0x6261
cmpl 0x4a1f(%rip), %esi      # 0xabcc
jbe 0x6261
movl $0xffffffff, 0x4a0f(%rip) # imm = 0xFFFFFFFF
movl $0x2, %r15d
jmp 0x626f
testl %r14d, %r14d
je 0x62f4
movl 0x49c9(%rip), %edi      # 0xaba0
subl %edi, %esi
addq %rbx, %rdi
movq %r14, -0x38(%rbp)
leal -0x1(%r14), %edx
xorl %r15d, %r15d
xorl %ecx, %ecx
callq 0x5a95
movl 0x49b8(%rip), %eax      # 0xabac
movl %eax, 0x49a6(%rip)      # 0xaba0
movl $0x2, %r13d
jmp 0x62c8
cmpl $0x0, 0x1047934(%rip)   # 0x104db40
movl 0x499a(%rip), %esi      # 0xabac
je 0x62b1
cmpl 0x49ae(%rip), %esi      # 0xabcc
jbe 0x629f
movl $0xffffffff, 0x49a2(%rip) # imm = 0xFFFFFFFF
movl 0x4970(%rip), %edi      # 0xaba0
subl %edi, %esi
addq %rbx, %rdi
movl $0x1, %edx
xorl %ecx, %ecx
callq 0x5a95
movl 0x4965(%rip), %esi      # 0xabac
movl %esi, 0x4953(%rip)      # 0xaba0
movl $0x2, %eax
movq %rax, -0x38(%rbp)
cmpl $0x0, 0x10478e3(%rip)   # 0x104db40
jne 0x629f
jmp 0x62b1
movl $0x1, %r15d
testl %eax, %eax
je 0x6307
movl 0x492b(%rip), %edi      # 0xaba0
subl %edi, %esi
addq %rbx, %rdi
leal -0x1(%r15), %edx
xorl %ecx, %ecx
callq 0x5a95
movl 0x4921(%rip), %esi      # 0xabac
movl %esi, 0x490f(%rip)      # 0xaba0
movl 0x10478a9(%rip), %ecx   # 0x104db40
testl %ecx, %ecx
movq %r15, -0x38(%rbp)
je 0x62b1
movl %esi, %edi
movl $0x1, %esi
callq 0x5ede
movl 0x48fb(%rip), %esi      # 0xabac
decl 0x48fd(%rip)            # 0xabb4
incl %esi
movl %esi, 0x48ed(%rip)      # 0xabac
movl $0x1, %r15d
movl %r14d, %r13d
movl 0x48e6(%rip), %eax      # 0xabb4
cmpl $0x105, %eax            # imm = 0x105
ja 0x62ea
movl 0x1007845(%rip), %ecx   # 0x100db20
cmpl %ecx, 0x1007843(%rip)   # 0x100db24
je 0x62ea
callq 0x5dd8
jmp 0x62c8
testl %eax, %eax
jne 0x5fd1
jmp 0x630c
movl $0x2, %r13d
movq $0x0, -0x38(%rbp)
xorl %r15d, %r15d
jmp 0x62c8
xorl %r15d, %r15d
jmp 0x6297
movl 0x489a(%rip), %esi      # 0xabac
cmpb $0x0, -0x29(%rbp)
jne 0x632b
decl %esi
movzbl (%rsi,%rbx), %esi
xorl %edi, %edi
callq 0x5c5e
movl 0x4881(%rip), %esi      # 0xabac
movq -0x38(%rbp), %rdx
decl %edx
movl 0x4869(%rip), %eax      # 0xaba0
addq %rax, %rbx
subl %eax, %esi
movq %rbx, %rdi
movl $0x1, %ecx
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x5a95