// File: /workspace/github_c_makefile_star2_O2/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
pushq $0x2
popq %r13
xorl %r12d, %r12d
movl 0x517e(%rip), %ecx      # 0xaba4
leaq 0x1008103(%rip), %rbx   # 0x100db30
leaq 0x10180fc(%rip), %r14   # 0x101db30
movq %rax, -0x30(%rbp)
movl %r13d, %eax
testl %ecx, %ecx
je 0x5d5e
movl %r12d, -0x34(%rbp)
movl 0x5147(%rip), %esi      # 0xab94
shll $0x5, %esi
movl 0x5146(%rip), %ecx      # 0xab9c
leal 0x2(%rcx), %edx
movzbl (%rdx,%rbx), %edx
andl $0x7fe0, %esi           # imm = 0x7FE0
xorl %edx, %esi
movl %esi, 0x5129(%rip)      # 0xab94
movzwl 0x10000(%r14,%rsi,2), %edx
movzwl %dx, %edi
movl %ecx, %r8d
andl $0x7fff, %r8d           # imm = 0x7FFF
movw %di, (%r14,%r8,2)
movw %cx, 0x10000(%r14,%rsi,2)
movl %eax, 0x5103(%rip)      # 0xab98
movl 0x5104(%rip), %r12d     # 0xaba0
movl %ecx, %esi
subl %edi, %esi
movl %r13d, %r15d
cmpl $0x7efa, %esi           # imm = 0x7EFA
ja 0x5b06
movl %r13d, %r15d
testw %dx, %dx
je 0x5b06
movl %r13d, %r15d
cmpl 0x50f0(%rip), %eax      # 0xabac
jae 0x5b06
movl 0x490c(%rip), %eax      # 0xa3d0
movl $0xfffffefa, %edx       # imm = 0xFFFFFEFA
addl %edx, %eax
movl %r13d, %r15d
cmpl %eax, %ecx
ja 0x5b06
callq 0x47ae
movl 0x50c6(%rip), %r15d     # 0xaba4
cmpl %r15d, %eax
cmovbl %eax, %r15d
cmpl $0x3, %r15d
jne 0x5b06
movl 0x50ab(%rip), %eax      # 0xab9c
subl 0x50a9(%rip), %eax      # 0xaba0
cmpl $0x1001, %eax           # imm = 0x1001
movl $0x0, %r15d
adcl $0x2, %r15d
movl 0x508c(%rip), %esi      # 0xab98
cmpl $0x3, %esi
jb 0x5be9
cmpl %esi, %r15d
ja 0x5be9
notl %r12d
addl 0x5074(%rip), %r12d     # 0xab9c
addl $-0x3, %esi
movl %r12d, %edi
callq 0x56cf
movl 0x505e(%rip), %r8d      # 0xab98
leal -0x1(%r8), %esi
subl %esi, 0x5060(%rip)      # 0xaba4
addl $-0x2, %r8d
movl %r8d, 0x5049(%rip)      # 0xab98
cmpl $0x0, 0x1047fda(%rip)   # 0x104db30
je 0x5b70
movl 0x503e(%rip), %edi      # 0xab9c
movq %rax, %r15
callq 0x5953
movq %r15, %rax
movl 0x5028(%rip), %r8d      # 0xab98
movl 0x5026(%rip), %esi      # 0xab9c
movl 0x5018(%rip), %ecx      # 0xab94
incl %esi
movl %r13d, %r15d
shll $0x5, %ecx
leal 0x2(%rsi), %edx
movzbl (%rdx,%rbx), %edx
andl $0x7fe0, %ecx           # imm = 0x7FE0
xorl %edx, %ecx
movzwl 0x10000(%r14,%rcx,2), %edx
movl %esi, %edi
andl $0x7fff, %edi           # imm = 0x7FFF
movw %dx, (%r14,%rdi,2)
movw %si, 0x10000(%r14,%rcx,2)
incl %esi
decl %r8d
jne 0x5b81
andl $0x0, 0x4fd8(%rip)      # 0xab98
movl %ecx, 0x4fce(%rip)      # 0xab94
movl %esi, 0x4fd0(%rip)      # 0xab9c
cmpl $0x0, 0x1047f5d(%rip)   # 0x104db30
je 0x5c35
cmpl 0x4fe1(%rip), %esi      # 0xabbc
jbe 0x5c35
orl $-0x1, 0x4fd8(%rip)     # 0xabbc
movl %r15d, %eax
jmp 0x5c3d
cmpl $0x0, -0x34(%rbp)
je 0x5c6a
movl 0x4fa7(%rip), %eax      # 0xab9c
decl %eax
movzbl (%rax,%rbx), %esi
xorl %edi, %edi
callq 0x56cf
movl 0x1047f28(%rip), %ecx   # 0x104db30
movl 0x4f8e(%rip), %esi      # 0xab9c
testl %ecx, %ecx
pushq $0x1
popq %r12
je 0x5cc3
cmpl 0x4f9c(%rip), %esi      # 0xabbc
jbe 0x5cc3
orl $-0x1, 0x4f8f(%rip)     # 0xabbc
movl %r13d, %edx
jmp 0x5cce
testl %eax, %eax
je 0x5d47
movl 0x4f4d(%rip), %edi      # 0xab90
subl %edi, %esi
addq %rbx, %rdi
movq %rax, -0x30(%rbp)
leal -0x1(%rax), %edx
xorl %r12d, %r12d
xorl %ecx, %ecx
callq 0x5526
movl 0x4f3d(%rip), %eax      # 0xab9c
movl %eax, 0x4f2b(%rip)      # 0xab90
jmp 0x5d1a
cmpl $0x0, 0x1047ebf(%rip)   # 0x104db30
movl 0x4f25(%rip), %esi      # 0xab9c
pushq $0x1
popq %r12
je 0x5d0c
cmpl 0x4f35(%rip), %esi      # 0xabbc
jbe 0x5cfc
orl $-0x1, 0x4f2c(%rip)     # 0xabbc
movl 0x4efa(%rip), %edi      # 0xab90
subl %edi, %esi
addq %rbx, %rdi
movl %r12d, %edx
xorl %ecx, %ecx
callq 0x5526
movl 0x4ef1(%rip), %esi      # 0xab9c
movl %esi, 0x4edf(%rip)      # 0xab90
cmpl $0x0, 0x1047e78(%rip)   # 0x104db30
movl %r13d, %eax
movq %rax, -0x30(%rbp)
jne 0x5cfc
jmp 0x5d0c
movl %r12d, %edx
testl %eax, %eax
je 0x5d54
movl 0x4ebc(%rip), %edi      # 0xab90
subl %edi, %esi
addq %rbx, %rdi
movq %rdx, -0x30(%rbp)
decl %edx
xorl %ecx, %ecx
callq 0x5526
movl 0x4eb0(%rip), %esi      # 0xab9c
movl %esi, 0x4e9e(%rip)      # 0xab90
movl 0x1047e38(%rip), %ecx   # 0x104db30
testl %ecx, %ecx
je 0x5d0c
movl %esi, %edi
movl %r12d, %esi
callq 0x5953
movl 0x4e90(%rip), %esi      # 0xab9c
incl %esi
movl %esi, 0x4e88(%rip)      # 0xab9c
decl 0x4e8a(%rip)            # 0xaba4
movl 0x4e84(%rip), %ecx      # 0xaba4
movl 0x1007dee(%rip), %eax   # 0x100db14
movl 0x1007de4(%rip), %edx   # 0x100db10
cmpl $0x105, %ecx            # imm = 0x105
ja 0x5d3f
cmpl %edx, %eax
je 0x5d3f
callq 0x5849
jmp 0x5d1a
movl %r15d, %eax
jmp 0x5a3b
movq $0x0, -0x30(%rbp)
xorl %r12d, %r12d
jmp 0x5d1a
movq $0x0, -0x30(%rbp)
jmp 0x5cf8
movl 0x4e38(%rip), %esi      # 0xab9c
testl %r12d, %r12d
je 0x5d7c
decl %esi
movzbl (%rsi,%rbx), %esi
xorl %edi, %edi
callq 0x56cf
movl 0x4e20(%rip), %esi      # 0xab9c
movl 0x4e0e(%rip), %eax      # 0xab90
addq %rax, %rbx
subl %eax, %esi
movq -0x30(%rbp), %rdx
decl %edx
pushq $0x1
popq %rcx
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x5526