// File: /workspace/github_c_makefile_star2_O3/salextpuru[P]speccy-toochain/src/megalz/MegaLZ_pack.c
// Function: make_LZ_codes
void make_LZ_codes(ULONG curpos)
{ // actual generation of all LZ codes for the given byte @curpos
  // result in codes[256] array (see MegaLZ_lz.h, MegaLZ_lz.c)

	UBYTE curbyte,nextbyte;
	ULONG i;
	ULONG tbi;
	ULONG was_twobyter,last_match;
	ULONG lzlen;

	struct tb_chain * curtb;



	tbi=0;
	curtb=NULL;

	// init lz codes collecting
	start_lz();


	// find 1-byte code

	curbyte=indata[curpos];

	i=(curpos>8)?(curpos-8):0;
	while( i<curpos )
	{
		if( indata[i]==curbyte )
		{
			add_lz((LONG)i-(LONG)curpos,1);
			break;
		}

		i++;
	}



	// find 2-byte code

	was_twobyter=0;

	if( (inlen-1)>curpos ) // if we have enough bytes ahead
	{
		nextbyte=indata[curpos+1];
		tbi=(((ULONG)curbyte)<<8)+((ULONG)nextbyte);

		curtb=tb_entry[tbi]; // get twobyter

		if( curtb )
		{
			if( (curpos-curtb->pos)<=256 )
			{
				add_lz((LONG)curtb->pos-(LONG)curpos,2);
			}

			if( (curpos-curtb->pos)<=4352 )
			{
				was_twobyter=1; // there is something for 3 and more bytes finding
			}
			else
			{
				cutoff_twobyte_chain(tbi,curpos); // flush older twobyters
			}
		}
	}



	// find other codes (len=3..255)

	if( was_twobyter && ((inlen-2)>curpos) ) // was twobyter within -1..-4352 range
	                                         // and at least 3-byter possible
	{
		// some inits

		//curtb=tb_entry[tbi]; // already done in 2-byter search

		last_match=1; // was last match (for 2 bytes)

		// loop for all possible lengths
		for( lzlen=3; (lzlen<=255)&&((inlen-lzlen+1)>curpos);/*NOTHING!*/)
		{
			if( last_match )
			{ // there were last match (lzlen-1)

				// compare last bytes of current match
				if( indata[curpos+lzlen-1]==indata[curtb->pos+lzlen-1] )
				{ // current match OK
					add_lz((LONG)curtb->pos-(LONG)curpos,lzlen);
					lzlen++;
				}
				else
				{ // current match failed: - take next (older) twobyter
MATCH_FAILED:
					curtb=curtb->next;
					if( !curtb ) break; // stop search if no more twobyters
					if( (curpos-curtb->pos)>4352 )
					{ // if twobyters out of range
						cutoff_twobyte_chain(tbi,curpos);
						break;
					}
					last_match=0; // indicate match fail for next step
				}
			}
			else
			{ // last match failed so compare all strings

				// first compare hashes of the ends of both strings
				if( hash[curpos+lzlen-1]==hash[curtb->pos+lzlen-1] )
				{
					// if hashes are the same, compare complete strings
					if( !memcmp( &indata[curpos], &indata[curtb->pos], lzlen) )
					{ //match OK
						last_match=1;
						add_lz((LONG)curtb->pos-(LONG)curpos,lzlen);
						lzlen++;
					}
					else goto MATCH_FAILED;
				}
				else goto MATCH_FAILED;
			}
		}
	}

	// stop collecting codes
	end_lz();

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %edi, %ebx
callq 0x1e6c
leaq 0x2cab(%rip), %rbp      # 0x50e0
movq (%rbp), %rax
movl %ebx, %ecx
movq %rcx, 0x8(%rsp)
movzbl (%rax,%rcx), %r14d
xorl %edx, %edx
movl %ebx, %ecx
subl $0x8, %ecx
cmovbl %edx, %ecx
cmpl %ebx, %ecx
jae 0x247d
movl %ecx, %ecx
cmpl $0x8, %ebx
movl $0x8, %edi
cmovbl %ebx, %edi
addq %rcx, %rax
cmpb %r14b, (%rax)
je 0x2471
incq %rax
decl %edi
jne 0x2463
jmp 0x247d
negl %edi
movl $0x1, %esi
callq 0x1ea0
leaq 0x2c54(%rip), %r8       # 0x50d8
movl (%r8), %eax
decl %eax
cmpl %ebx, %eax
jbe 0x25ca
movq (%rbp), %rax
movq 0x8(%rsp), %rcx
movzbl 0x1(%rcx,%rax), %eax
shll $0x8, %r14d
orl %eax, %r14d
leaq 0x51a3(%rip), %rax      # 0x7650
movq (%rax,%r14,8), %r13
testq %r13, %r13
je 0x25ca
movl 0x8(%r13), %edi
movl %ebx, %eax
subl %edi, %eax
cmpl $0x100, %eax            # imm = 0x100
ja 0x24e1
subl %ebx, %edi
movl $0x2, %esi
movq %r8, %r12
callq 0x1ea0
movq %r12, %r8
movl %ebx, %eax
subl 0x8(%r13), %eax
cmpl $0x1100, %eax           # imm = 0x1100
ja 0x25c0
movl (%r8), %eax
addl $-0x2, %eax
cmpl %ebx, %eax
jbe 0x25ca
leal -0x1(%rbx), %eax
movq %rax, 0x10(%rsp)
movl $0x1, %eax
movl $0x3, %r15d
movl (%r8), %ecx
subl %r15d, %ecx
incl %ecx
cmpl %ebx, %ecx
jbe 0x25ca
movq 0x10(%rsp), %rcx
addl %r15d, %ecx
movl 0x8(%r13), %r12d
leal (%r15,%r12), %edx
decl %edx
testl %eax, %eax
je 0x2563
movq (%rbp), %rax
movb (%rax,%rcx), %cl
cmpb (%rax,%rdx), %cl
jne 0x2598
subl %ebx, %r12d
movl %r12d, %edi
movq %rbp, %r12
movl %r15d, %esi
movq %r8, %rbp
callq 0x1ea0
movq %rbp, %r8
movq %r12, %rbp
incl %r15d
movl $0x1, %eax
jmp 0x25b1
leaq 0x4ca6(%rip), %rax      # 0x7210
movq (%rax), %rax
movb (%rax,%rcx), %cl
cmpb (%rax,%rdx), %cl
jne 0x2598
movq (%rbp), %rsi
movq 0x8(%rsp), %rax
leaq (%rsi,%rax), %rdi
addq %r12, %rsi
movl %r15d, %edx
callq 0x10a0
leaq 0x2b44(%rip), %r8       # 0x50d8
testl %eax, %eax
je 0x253f
movq (%r13), %r13
testq %r13, %r13
je 0x25ca
movl %ebx, %ecx
subl 0x8(%r13), %ecx
xorl %eax, %eax
cmpl $0x1100, %ecx           # imm = 0x1100
ja 0x25c0
cmpl $0x100, %r15d           # imm = 0x100
jb 0x250d
jmp 0x25ca
movl %r14d, %edi
movl %ebx, %esi
callq 0x27d7
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1e77