// File: /workspace/github_c_makefile_star2_O0/DavidSM64[P]DKR-Decompressor/GECompression.cpp
// Function: GECompression::DecompressBasedOnTable(int, int, int, int, unsigned char*, int&)
bool GECompression::DecompressBasedOnTable(int startIndex1, int startIndex2, int bitLen1, int bitLen2, unsigned char* returnBuffer, int& fileSize)
{
	unsigned long index = 0;
	bool exitFlag = 1;

	try
	{

	while (exitFlag)
	{

		if (iterationCounter > 268435455)
		{
			fileSize = 0;
			return false;
		}
		iterationCounter++;

		if (bytesIndex >= maxByteSize)
		{
			fileSize = 0;
			return false;
		}
		index = GetNBitsAndPreserve(bitLen1);
		if ((startIndex1 + index) > 0xFFFF)
		{
			fileSize = 0;
			return false;
		}
		tableEntry entry = unpackTable[startIndex1 + index];

		while (entry.flags > 0x10)
		{
			if (iterationCounter > 268435455)
			{
				fileSize = 0;
				return false;
			}
			iterationCounter++;

			if (bytesIndex >= maxByteSize)
			{
				fileSize = 0;
				return false;
			}
			GetNBits(entry.bits); // discard
			index = GetNBitsAndPreserve(entry.flags-0x10);
			if ((entry.nextIndex+index) > 0xFFFF)
			{
				fileSize = 0;
				return false;
			}
			entry = unpackTable[entry.nextIndex+index];
		}
		if (bytesIndex >= maxByteSize)
		{
			fileSize = 0;
			return false;
		}
		GetNBits(entry.bits); // discard
		
		if (entry.flags==0x10)
		{
			if (fileSize >= maxByteSize)
			{
				fileSize = 0;
				return false;
			}
			returnBuffer[fileSize] = entry.wordValue;
			fileSize++;
		}
		else if (entry.flags < 0xf)
		{
			unsigned long copyLen = entry.wordValue + GetNBits(entry.flags);
			unsigned long index2 = GetNBitsAndPreserve(bitLen2);
			if ((startIndex2+index2) > 0xFFFF)
			{
				fileSize = 0;
				return false;
			}
			tableEntry entry2 = unpackTable[startIndex2+index2];
			while (entry2.flags>0x10)
			{

				if (iterationCounter > 268435455)
				{
					fileSize = 0;
					return false;
				}
				iterationCounter++;

				if (bytesIndex >= maxByteSize)
				{
					fileSize = 0;
					return false;
				}
				GetNBits(entry2.bits); // discard
				index2 = GetNBitsAndPreserve(entry2.flags-0x10);
				if ((entry2.nextIndex+index2) > 0xFFFF)
				{
					fileSize = 0;
					return false;
				}
				entry2 = unpackTable[entry2.nextIndex+index2];
			}
			if (bytesIndex >= maxByteSize)
			{
				fileSize = 0;
				return false;
			}
			GetNBits(entry2.bits); // discard

			unsigned long endOffset1 = entry2.wordValue;
			unsigned long endOffset2 = GetNBits(entry2.flags);
			unsigned long start = fileSize-endOffset1-endOffset2;
			unsigned long end = start + copyLen;
			for (int x = start; x < end; x++)
			{
				if ((((signed long) start) < 0) || ((((signed long) end) < 0)) || ((start > maxByteSize)) || ((end > maxByteSize)))
				{
					fileSize = 0;
					return false;
				}
				returnBuffer[fileSize] = returnBuffer[x];
				fileSize++;
			}
		}
		else
			exitFlag = 0;
	}

	} catch (...)
	{
		return false;
	}
	return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq 0x10(%rbp), %rax
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movl %r8d, -0x20(%rbp)
movq %r9, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq $0x0, -0x30(%rbp)
movb $0x1, -0x31(%rbp)
testb $0x1, -0x31(%rbp)
je 0x88a6
movq -0xa8(%rbp), %rax
cmpq $0xfffffff, 0x80(%rax) # imm = 0xFFFFFFF
jbe 0x83ec
movq 0x10(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x88aa
movq -0xa8(%rbp), %rax
movq 0x80(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x80(%rax)
cmpq $0x800000, 0x48(%rax)   # imm = 0x800000
jb 0x8422
movq 0x10(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x88aa
movq -0xa8(%rbp), %rdi
movl -0x1c(%rbp), %esi
callq 0x6530
movq %rax, -0x30(%rbp)
movslq -0x14(%rbp), %rax
addq -0x30(%rbp), %rax
cmpq $0xffff, %rax           # imm = 0xFFFF
jbe 0x8458
movq 0x10(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x88aa
movq -0xa8(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x14(%rbp), %rcx
addq -0x30(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rcx
movq %rcx, -0x50(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x48(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x40(%rbp)
movzbl -0x48(%rbp), %eax
cmpl $0x10, %eax
jle 0x8575
movq -0xa8(%rbp), %rax
cmpq $0xfffffff, 0x80(%rax) # imm = 0xFFFFFFF
jbe 0x84bd
movq 0x10(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x88aa
movq -0xa8(%rbp), %rax
movq 0x80(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x80(%rax)
cmpq $0x800000, 0x48(%rax)   # imm = 0x800000
jb 0x84f3
movq 0x10(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x88aa
movq -0xa8(%rbp), %rdi
movq -0x50(%rbp), %rax
movl %eax, %esi
callq 0x6440
movq -0xa8(%rbp), %rdi
movzbl -0x48(%rbp), %esi
subl $0x10, %esi
callq 0x6530
movq %rax, -0x30(%rbp)
movslq -0x44(%rbp), %rax
addq -0x30(%rbp), %rax
cmpq $0xffff, %rax           # imm = 0xFFFF
jbe 0x853f
movq 0x10(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x88aa
movq -0xa8(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x44(%rbp), %rcx
addq -0x30(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rcx
movq %rcx, -0x50(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x48(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x8489
movq -0xa8(%rbp), %rax
cmpq $0x800000, 0x48(%rax)   # imm = 0x800000
jb 0x8599
movq 0x10(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x88aa
movq -0xa8(%rbp), %rdi
movq -0x50(%rbp), %rax
movl %eax, %esi
callq 0x6440
movzbl -0x48(%rbp), %eax
cmpl $0x10, %eax
jne 0x85f7
movq 0x10(%rbp), %rax
cmpl $0x800000, (%rax)       # imm = 0x800000
jl 0x85d3
movq 0x10(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x88aa
movq -0x40(%rbp), %rax
movb %al, %dl
movq -0x28(%rbp), %rax
movq 0x10(%rbp), %rcx
movslq (%rcx), %rcx
movb %dl, (%rax,%rcx)
movq 0x10(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x88a1
movzbl -0x48(%rbp), %eax
cmpl $0xf, %eax
jge 0x889b
movq -0xa8(%rbp), %rdi
movq -0x40(%rbp), %rax
movq %rax, -0xb0(%rbp)
movzbl -0x48(%rbp), %esi
callq 0x6440
movq -0xa8(%rbp), %rdi
movq %rax, %rcx
movq -0xb0(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x58(%rbp)
movl -0x20(%rbp), %esi
callq 0x6530
movq %rax, -0x60(%rbp)
movslq -0x18(%rbp), %rax
addq -0x60(%rbp), %rax
cmpq $0xffff, %rax           # imm = 0xFFFF
jbe 0x8666
movq 0x10(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x88aa
movq -0xa8(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x18(%rbp), %rcx
addq -0x60(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rcx
movq %rcx, -0x78(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x70(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x68(%rbp)
movzbl -0x70(%rbp), %eax
cmpl $0x10, %eax
jle 0x8783
movq -0xa8(%rbp), %rax
cmpq $0xfffffff, 0x80(%rax) # imm = 0xFFFFFFF
jbe 0x86cb
movq 0x10(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x88aa
movq -0xa8(%rbp), %rax
movq 0x80(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x80(%rax)
cmpq $0x800000, 0x48(%rax)   # imm = 0x800000
jb 0x8701
movq 0x10(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x88aa
movq -0xa8(%rbp), %rdi
movq -0x78(%rbp), %rax
movl %eax, %esi
callq 0x6440
movq -0xa8(%rbp), %rdi
movzbl -0x70(%rbp), %esi
subl $0x10, %esi
callq 0x6530
movq %rax, -0x60(%rbp)
movslq -0x6c(%rbp), %rax
addq -0x60(%rbp), %rax
cmpq $0xffff, %rax           # imm = 0xFFFF
jbe 0x874d
movq 0x10(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x88aa
movq -0xa8(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x6c(%rbp), %rcx
addq -0x60(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rcx
movq %rcx, -0x78(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x70(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x68(%rbp)
jmp 0x8697
movq -0xa8(%rbp), %rax
cmpq $0x800000, 0x48(%rax)   # imm = 0x800000
jb 0x87a7
movq 0x10(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x88aa
movq -0xa8(%rbp), %rdi
movq -0x78(%rbp), %rax
movl %eax, %esi
callq 0x6440
movq -0xa8(%rbp), %rdi
movq -0x68(%rbp), %rax
movq %rax, -0x80(%rbp)
movzbl -0x70(%rbp), %esi
callq 0x6440
movq %rax, -0x88(%rbp)
movq 0x10(%rbp), %rax
movslq (%rax), %rax
subq -0x80(%rbp), %rax
subq -0x88(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
addq -0x58(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x90(%rbp), %rax
movl %eax, -0x9c(%rbp)
movslq -0x9c(%rbp), %rax
cmpq -0x98(%rbp), %rax
jae 0x8899
cmpq $0x0, -0x90(%rbp)
jl 0x884e
cmpq $0x0, -0x98(%rbp)
jl 0x884e
cmpq $0x800000, -0x90(%rbp) # imm = 0x800000
ja 0x884e
cmpq $0x800000, -0x98(%rbp) # imm = 0x800000
jbe 0x885e
movq 0x10(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x88aa
movq -0x28(%rbp), %rax
movslq -0x9c(%rbp), %rcx
movb (%rax,%rcx), %dl
movq -0x28(%rbp), %rax
movq 0x10(%rbp), %rcx
movslq (%rcx), %rcx
movb %dl, (%rax,%rcx)
movq 0x10(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0x8810
jmp 0x889f
movb $0x0, -0x31(%rbp)
jmp 0x88a1
jmp 0x83bb
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xb0, %rsp
popq %rbp
retq
nopl (%rax,%rax)