// File: /workspace/github_c_makefile_star2_O2/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 $0x38, %rsp
movl %edi, %ebx
callq 0x1cf4
leaq 0x2ed9(%rip), %rax      # 0x50e0
movq (%rax), %rax
movl %ebx, %r12d
movzbl (%rax,%r12), %r14d
xorl %edx, %edx
movl %ebx, %ecx
subl $0x8, %ecx
cmovbl %edx, %ecx
pushq $0x8
popq %rdi
cmovbl %ebx, %edi
negl %edi
cmpq %r12, %rcx
jae 0x223e
cmpb %r14b, (%rax,%rcx)
je 0x2236
incq %rcx
incl %edi
jmp 0x2224
pushq $0x1
popq %rsi
callq 0x1d25
leaq 0x2e93(%rip), %rcx      # 0x50d8
movl (%rcx), %eax
decl %eax
cmpl %ebx, %eax
jbe 0x23bd
leaq 0x2e88(%rip), %rax      # 0x50e0
movq (%rax), %rax
movzbl 0x1(%r12,%rax), %eax
shll $0x8, %r14d
orl %eax, %r14d
leaq 0x53e1(%rip), %rax      # 0x7650
movq (%rax,%r14,8), %rbp
testq %rbp, %rbp
je 0x23bd
movl 0x8(%rbp), %edi
movl %ebx, %eax
subl %edi, %eax
cmpl $0x100, %eax            # imm = 0x100
ja 0x22a0
subl %ebx, %edi
pushq $0x2
popq %rsi
callq 0x1d25
leaq 0x2e3d(%rip), %rcx      # 0x50d8
movl %ebx, %eax
subl 0x8(%rbp), %eax
cmpl $0x1100, %eax           # imm = 0x1100
ja 0x23b3
movl (%rcx), %eax
addl $-0x2, %eax
cmpl %ebx, %eax
jbe 0x23bd
leal -0x1(%rbx), %eax
pushq $0x3
popq %rsi
leaq 0x4f4b(%rip), %rdx      # 0x7210
movq %rax, 0x8(%rsp)
movl (%rcx), %edi
subl %esi, %edi
incl %edi
leal (%rax,%rsi), %r8d
leaq 0x2e05(%rip), %rax      # 0x50e0
movq (%rax), %r9
movq (%rdx), %r10
leaq (%r9,%r12), %rax
movq %rax, 0x10(%rsp)
movl %esi, %r15d
decl %esi
xorl %eax, %eax
movq %rsi, 0x30(%rsp)
movl %edi, 0x4(%rsp)
movq %r8, 0x28(%rsp)
movq %r9, 0x20(%rsp)
movq %r10, 0x18(%rsp)
cmpl $0xff, %r15d
ja 0x23bd
cmpl %ebx, %edi
jbe 0x23bd
movl 0x8(%rbp), %r13d
leal (%rsi,%r13), %ecx
testb $0x1, %al
je 0x2363
movb (%r10,%r8), %al
cmpb (%r10,%rcx), %al
jne 0x236d
leaq (%r9,%r13), %rsi
movq 0x10(%rsp), %rdi
movq %r15, %rdx
callq 0x1090
movq 0x18(%rsp), %r10
movq 0x20(%rsp), %r9
movq 0x28(%rsp), %r8
movl 0x4(%rsp), %edi
movq 0x30(%rsp), %rsi
testl %eax, %eax
jne 0x236d
jmp 0x2387
movb (%r9,%r8), %al
cmpb (%r9,%rcx), %al
je 0x2387
movq (%rbp), %rbp
testq %rbp, %rbp
je 0x23bd
movl %ebx, %ecx
subl 0x8(%rbp), %ecx
movb $0x1, %al
cmpl $0x1100, %ecx           # imm = 0x1100
jbe 0x2309
jmp 0x23b3
subl %ebx, %r13d
movl %r13d, %edi
movl %r15d, %esi
callq 0x1d25
leaq 0x4e74(%rip), %rdx      # 0x7210
leaq 0x2d35(%rip), %rcx      # 0x50d8
incl %r15d
movl %r15d, %esi
movq 0x8(%rsp), %rax
jmp 0x22ca
movl %r14d, %edi
movl %ebx, %esi
callq 0x25a2
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1cfc