// File: /workspace/github_c_makefile_star2_O1/anuwu[P]ERPLAG-Compiler/codegen.c
// Function: moduleGeneration
void moduleGeneration (astNode *node, moduleST *lst)
{
	if (node == NULL)
		return ;

	varST *searchedVar ;
	astNode *idListHead ;
	moduleST *calledModule ;
	varSTentry *varEntry ;

	switch (node->id)
	{
		int start_label, end_label ;
		int reserveLabel[10] ;

		case statements :
			if (node->child == NULL && node->localST->parent == realBase)
				retModule (node->localST) ;
			else
				moduleGeneration (node->child, node->localST);		// Access local scope and move below

			break ;

		case statement :
		{
			moduleGeneration(node->child, lst);
			if (node->next == NULL)
			{
				if (lst->tableType == SWITCH_ST)
					break ;

				varEntry = lst->dynamicVars[0] ;
				freeDynamic (varEntry) ;

				if (lst->parent == realBase)
					retModule (lst) ;
				else if (lst->scopeSize > 0)
				{
					codePrint ("\n\t\tADD RSP, %d", lst->scopeSize) ;
					codeComment (10, "restoring to parent scope") ;
				}

			}
			else
				moduleGeneration(node->next, lst);

			break ;
		}

		case TK_DECLARE :
		{
			;
			switchDeclareStatus stat ;
			if (lst->tableType != SWITCH_ST)
				stat = NOT_SWITCH ; // Subtract RSP, and allocate memory if dynamic
			else if (node->parent != node)
				stat = SWITCH_INIT ; // Subtract RSP only, and do not allocate memory for dynamic
			else
			{
				stat = SWITCH_GEN ; // Do not subtract RSP, allocate memory if dynamic AND restore parent
				node->parent = node->next->parent ;
			}

			int declCount = 1 ;
			idListHead = node->next->child ;
			astNode *dtNode = node->next->next ;

			while (idListHead->next != NULL)
			{
				declCount++ ;
				idListHead = idListHead->next ;
			}

			searchedVar = searchVar (lst, idListHead->tok->lexeme) ;
			if (searchedVar->size > 0 && stat != SWITCH_GEN)
			{	
				codePrint ("\t\tSUB RSP, %d", searchedVar->size * declCount) ;
				if (stat == NOT_SWITCH)
					codeComment (11, "making space for declaration") ;
				else if (stat == SWITCH_INIT)
					codeComment (11, "declaring before switch") ;

				codePrint ("\n") ;
			}

			if (dtNode->dtTag == ARRAY && !isVarStaticArr(searchedVar) && stat != SWITCH_GEN)
				dynamicDeclaration (lst, searchedVar, declCount) ;

			break ;	
		}									

		case TK_ASSIGNOP :
		{
			if (isSingleRHS(node))
			{
				if (isArrayRHS (node, lst))
				{
					//printf ("CANNOT HANDLE ARRAY ASSIGNMENT YET\n") ;
					varST *lhs, *rhs ;
					lhs = searchVar (lst, node->child->tok->lexeme) ;
					rhs = searchVar (lst, node->child->next->tok->lexeme) ;
				
					if (isVarStaticArr (lhs) && isVarStaticArr (rhs))
					{
						tf |= 1 << asgnArr ;

						loadRegLeftLim (lhs, "CX") ;
						loadRegRightLim (lhs, "DX") ;
						loadArrBase (lhs, "RDI") ;
						loadArrBase (rhs, "RSI") ;
						codePrint ("\t\tSUB DX, CX\n") ;
						codePrint ("\t\tADD DX, 1\n") ;
						codePrint ("\t\tADD DX, DX\n") ;
						codePrint ("\t\tCALL @asgnArr\n") ;
					}
					else
						dynAsgnArr (lhs, rhs) ;
				}
				else
				{
					expr(node->child->next, lst, 1);
					exprAssign (node->child, lst, 1) ;
				}
			}
			else
			{
				int singleAssign = 0 ;

				if (isAssignUnary (node))
				{
					if (isExprLeaf (node->child->next->child->id))
						singleAssign = 1 ;

					expr(node->child->next->child, lst, singleAssign) ;
				}
				else
					expr(node->child->next, lst, 0);	

				exprAssign (node->child, lst, singleAssign) ;
			}

			codePrint ("\n") ;
			break ;
		}

		case TK_FOR :
		{
			node=node->next;
			start_label = get_label (LABEL_FOR) ;
			end_label = get_label (LABEL_FOR) ;

			searchedVar = searchVar (lst, node->tok->lexeme) ;

			codePrint ("\t\tMOV CX,%s\n", node->next->tok->lexeme);
			codePrint ("\t\tMOV [RBP%s], CX" , getOffsetStr(searchedVar->offset)) ;

			codePrint ("\n\t@FOR%d:\n", start_label) ;
			codePrint ("\t\tMOV AX, %s\n", node->next->next->tok->lexeme) ;
			codePrint ("\t\tCMP CX, AX\n");
			codePrint ("\t\tJG @FOR%d\n\n", end_label);

			moduleGeneration(node->next->next->next, lst);		// Statements

			codePrint ("\n\t\tMOV CX, [RBP%s]", getOffsetStr(searchedVar->offset)) ;
			codeComment (8, "For loop increment") ;
			codePrint ("\t\tINC CX\n");
			codePrint ("\t\tMOV [RBP%s],CX\n", getOffsetStr(searchedVar->offset)) ;
			codePrint ("\t\tJMP @FOR%d\n", start_label) ;
			codePrint ("\n\t@FOR%d:\n", end_label) ;
			break ;
		}

		
		case TK_WHILE :
		{
			node=node->next;
			start_label = get_label(LABEL_WHILE);
			end_label =  get_label(LABEL_WHILE);

			codePrint ("\n\t@WHILE%d:\n", start_label) ;

			expr (node, lst, 0);	// expr

			codePrint ("\t\tPOP AX\n");
			codePrint ("\t\tCMP AX, 0");
			codeComment (11, "checking while loop condition") ;
			codePrint ("\t\tJE @WHILE%d\n\n", end_label) ;

			moduleGeneration(node->next, lst);		// statements

			codePrint ("\t\tJMP @WHILE%d\n", start_label) ;
			codePrint ("\n\t@WHILE%d:\n", end_label) ;

			break ;
		}
		
		case TK_PRINT :
			node = node->next ;
			print (node, lst) ;
			break ;

		case TK_GET_VALUE :
			searchedVar = searchVar (lst, node->next->tok->lexeme) ;
			getValue (lst, searchedVar) ;
			break ;

		case TK_SWITCH :
		{
			int i, caseCount, def_label ;
			int *caseLabels ;
			astNode *statementsNode = node->next->next->next->next ;

			switchDeclareVars (node->next->next->next->next) ;
			caseCount = getCaseCount (node->next->next->next->next) ;
			caseLabels = (int *) malloc (sizeof(int) * caseCount) ;
			def_label = switchCaseLabels (node , lst, caseCount, caseLabels) ;

			end_label = get_label (LABEL_SWITCH) ;
			i = 0 ;
			while (statementsNode != NULL)
			{
				codePrint ("\n@SWITCH%d:\n", caseLabels[i]) ;
				moduleGeneration (statementsNode, lst) ;
				codePrint ("\n\t\tJMP @SWITCH%d\n", end_label) ;

				i++ ;
				if (statementsNode->next != NULL)
				{
					if (statementsNode->next->id == TK_DEFAULT)
					{
						statementsNode = statementsNode->next->next ;
						codePrint ("\n@SWITCH%d:\n", def_label) ;
						moduleGeneration (statementsNode, lst) ;
						codePrint ("\n\t\tJMP @SWITCH%d\n", end_label) ;

						break ;
					}
					statementsNode = statementsNode->next->next->next ;
				}
				else
					statementsNode = NULL ;
			}

			statementsNode = node->next->next->next->next ;
			codePrint ("\n@SWITCH%d:\n", end_label) ;

			varEntry = statementsNode->localST->dynamicVars[0] ;
			freeDynamic (varEntry) ;

			if (statementsNode->localST->scopeSize > 0)
			{
				codePrint ("\t\tADD RSP, %d", statementsNode->localST->scopeSize) ;
				codeComment (11, "restoring to parent scope") ;
			}

			break ;
		}

		case TK_ID :
		{
			calledModule = searchModuleInbaseST (node->tok->lexeme) ;
			varEntry = calledModule->inputVars[0] ;

			idListHead = node->next->child ; 
			while (idListHead->next != NULL)
				idListHead = idListHead->next ;

			pushInput (idListHead, varEntry, lst) ;

			codePrint ("\t\tCALL %s", strcmp(node->tok->lexeme, "main") ? node->tok->lexeme : "@main") ;
			codeComment (11, "calling user function") ;
			codePrint ("\t\tADD RSP, %d\n", calledModule->inputSize) ;
			break ;
		}

		case idList :
		{
			calledModule = searchModuleInbaseST (node->next->next->tok->lexeme) ;
			varEntry = calledModule->inputVars[0] ;

			idListHead = node->next->next->next->child ;
			while (idListHead->next != NULL)
				idListHead = idListHead->next ;

			codePrint ("\t\tSUB RSP, %d\n", calledModule->outputSize) ;
			pushInput (idListHead, varEntry, lst) ;

			codePrint ("\t\tCALL %s", node->next->next->tok->lexeme) ;
			codeComment (11, "calling user function") ;
			codePrint ("\t\tADD RSP, %d\n", calledModule->inputSize) ;

			popOutput (node->child, lst) ;
			break ;
		}
	}

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %rbx
leaq 0x2f377(%rip), %r15     # 0x32028
movq %rdi, %r14
testq %r14, %r14
je 0x3671
movl (%r14), %eax
cmpl $0xd, %eax
jne 0x2cdf
movq 0x30(%r14), %rdi
movq %rbx, %rsi
callq 0x2c96
movq 0x38(%r14), %r14
testq %r14, %r14
jne 0x2cb4
jmp 0x3424
cmpl $0x4f, %eax
jg 0x2d19
leal -0x3e(%rax), %ecx
cmpl $0x6, %ecx
jbe 0x2d97
cmpl $0xc, %eax
jne 0x2ff3
movq 0x30(%r14), %rdi
testq %rdi, %rdi
jne 0x2d13
movq 0x20(%r14), %rax
movq 0x10(%rax), %rcx
cmpq (%r15), %rcx
je 0x36af
movq 0x20(%r14), %rbx
jmp 0x2cb1
cmpl $0x55, %eax
jg 0x2e9f
cmpl $0x50, %eax
je 0x31b0
cmpl $0x52, %eax
jne 0x3671
movq 0x38(%r14), %rax
movq 0x38(%rax), %rax
movq 0x38(%rax), %rax
movq 0x38(%rax), %r15
movq %r15, %rdi
callq 0x2c11
movq 0x38(%r14), %rax
movq 0x38(%rax), %rax
movq 0x38(%rax), %rax
movq 0x38(%rax), %rcx
testq %rcx, %rcx
je 0x347e
movl $0x1, %edx
movl %edx, %eax
movq 0x38(%rcx), %rcx
testq %rcx, %rcx
je 0x2d88
cmpl $0x55, (%rcx)
je 0x3480
movq 0x38(%rcx), %rcx
movq 0x38(%rcx), %rcx
jmp 0x2d8a
xorl %ecx, %ecx
leal 0x1(%rax), %edx
testq %rcx, %rcx
jne 0x2d6a
jmp 0x3480
leaq 0xd442(%rip), %rax      # 0x101e0
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movl 0x8(%rbx), %r13d
movb $0x1, %r12b
cmpl $0x4, %r13d
jne 0x2dc9
cmpq %r14, 0x28(%r14)
jne 0x2dc9
movq 0x38(%r14), %rax
movq 0x28(%rax), %rax
movq %rax, 0x28(%r14)
xorl %r12d, %r12d
movq 0x38(%r14), %rcx
movq 0x30(%rcx), %rax
movq 0x38(%rcx), %rcx
movq %rcx, -0x30(%rbp)
xorl %r14d, %r14d
movq %rax, %rcx
movq 0x38(%rax), %rax
incl %r14d
testq %rax, %rax
jne 0x2ddc
movq 0x8(%rcx), %rax
movq 0x8(%rax), %rsi
movq %rbx, %rdi
callq 0xc430
movq %rax, %r15
movl 0x18(%rax), %edx
testl %edx, %edx
setle %al
xorb $0x1, %r12b
orb %r12b, %al
jne 0x2e5f
leaq 0x15532(%rip), %rax     # 0x18348
movq (%rax), %rdi
imull %r14d, %edx
leaq 0xdc7e(%rip), %rsi      # 0x10aa2
xorl %eax, %eax
callq 0x1100
cmpl $0x4, %r13d
leaq 0xdc97(%rip), %rax      # 0x10acd
leaq 0xdc73(%rip), %rsi      # 0x10ab0
cmoveq %rax, %rsi
movl $0xb, %edi
callq 0x153a
leaq 0x154f6(%rip), %rax     # 0x18348
movq (%rax), %rsi
movl $0xa, %edi
callq 0x10e0
movq -0x30(%rbp), %rax
cmpl $0x1, 0x10(%rax)
jne 0x3671
movq %r15, %rdi
callq 0xe88a
testl %eax, %eax
setne %al
orb %al, %r12b
jne 0x3671
movq %rbx, %rdi
movq %r15, %rsi
movl %r14d, %edx
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x27d6
cmpl $0x56, %eax
je 0x3343
cmpl $0x69, %eax
jne 0x3671
movq 0x30(%r14), %rax
movq 0x38(%rax), %rdi
movl (%rdi), %eax
leal -0x40(%rax), %ecx
cmpl $0x31, %ecx
ja 0x3552
movabsq $0x2000000000301, %rdx  # imm = 0x2000000000301
btq %rcx, %rdx
jae 0x3552
movq %r14, %rdi
movq %rbx, %rsi
callq 0x191c
movq 0x30(%r14), %rcx
testl %eax, %eax
je 0x3533
movq 0x8(%rcx), %rax
movq 0x8(%rax), %rsi
movq %rbx, %rdi
callq 0xc430
movq %rax, %r15
movq 0x30(%r14), %rax
movq 0x38(%rax), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rsi
movq %rbx, %rdi
callq 0xc430
movq %rax, %rbx
movq %r15, %rdi
callq 0xe88a
testl %eax, %eax
je 0x3526
movq %rbx, %rdi
callq 0xe88a
testl %eax, %eax
je 0x3526
orb $-0x80, 0x15422(%rip)   # 0x18369
leaq 0xdbc8(%rip), %rsi      # 0x10b16
movq %r15, %rdi
callq 0x160f
leaq 0xd325(%rip), %rsi      # 0x10282
movq %r15, %rdi
callq 0x1678
leaq 0xd3a3(%rip), %rsi      # 0x1030f
movq %r15, %rdi
callq 0x16e1
leaq 0xdb6a(%rip), %rsi      # 0x10ae5
movq %rbx, %rdi
callq 0x16e1
leaq 0x153be(%rip), %rbx     # 0x18348
movq (%rbx), %rcx
leaq 0xd55c(%rip), %rdi      # 0x104f0
movl $0xd, %esi
movl $0x1, %edx
callq 0x1170
movq (%rbx), %rcx
leaq 0xd551(%rip), %rdi      # 0x104fe
movl $0xc, %esi
movl $0x1, %edx
callq 0x1170
movq (%rbx), %rcx
leaq 0xd545(%rip), %rdi      # 0x1050b
movl $0xd, %esi
movl $0x1, %edx
callq 0x1170
movq (%rbx), %rcx
leaq 0xdb0a(%rip), %rdi      # 0x10ae9
movl $0x10, %esi
movl $0x1, %edx
callq 0x1170
jmp 0x3585
cmpl $0x34, %eax
jne 0x3671
movq 0x38(%r14), %rax
movq 0x38(%rax), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rdi
callq 0xc2da
movq %rax, %r15
movq 0x88(%rax), %r12
movq 0x38(%r14), %rax
movq 0x38(%rax), %rax
movq 0x38(%rax), %rax
movq 0x30(%rax), %rax
movq %rax, %r13
movq 0x38(%rax), %rax
testq %rax, %rax
jne 0x302b
leaq 0x1530a(%rip), %rax     # 0x18348
movq (%rax), %rdi
movl 0x108(%r15), %edx
leaq 0xd76a(%rip), %rsi      # 0x107b9
xorl %eax, %eax
callq 0x1100
movq %r13, %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0x3a02
leaq 0x152dd(%rip), %r12     # 0x18348
movq (%r12), %rdi
movq 0x38(%r14), %rax
movq 0x38(%rax), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rdx
leaq 0xdb80(%rip), %rsi      # 0x10c06
xorl %eax, %eax
callq 0x1100
leaq 0xdb82(%rip), %rsi      # 0x10c16
movl $0xb, %edi
callq 0x153a
movq (%r12), %rdi
movl 0x104(%r15), %edx
leaq 0xd727(%rip), %rsi      # 0x107d7
xorl %eax, %eax
callq 0x1100
movq 0x30(%r14), %rdi
movq %rbx, %rsi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3b26
movq 0x8(%r14), %rax
movq 0x8(%rax), %rdi
callq 0xc2da
movq %rax, %r15
movq 0x88(%rax), %rsi
movq 0x38(%r14), %rax
movq 0x30(%rax), %rax
movq %rax, %rdi
movq 0x38(%rax), %rax
testq %rax, %rax
jne 0x30f0
movq %rbx, %rdx
callq 0x3a02
leaq 0x1523d(%rip), %r12     # 0x18348
movq (%r12), %rbx
movq 0x8(%r14), %rax
movq 0x8(%rax), %r14
leaq 0xdaf3(%rip), %rsi      # 0x10c11
movq %r14, %rdi
callq 0x10f0
testl %eax, %eax
leaq 0xdae1(%rip), %rdx      # 0x10c10
cmovneq %r14, %rdx
leaq 0xdacc(%rip), %rsi      # 0x10c06
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1100
leaq 0xdacb(%rip), %rsi      # 0x10c16
movl $0xb, %edi
callq 0x153a
movq (%r12), %rdi
movl 0x104(%r15), %edx
leaq 0xd670(%rip), %rsi      # 0x107d7
jmp 0x340f
movq 0x38(%r14), %rdi
movq %rbx, %rsi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x20c4
movq 0x38(%r14), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rsi
movq %rbx, %rdi
callq 0xc430
movq %rax, %rsi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x24c2
movq 0x38(%r14), %r12
movl 0x1519a(%rip), %ecx     # 0x18354
leal 0x1(%rcx), %eax
movl %eax, -0x30(%rbp)
addl $0x2, %ecx
movq %rcx, -0x38(%rbp)
movl %ecx, 0x15187(%rip)     # 0x18354
movq 0x8(%r12), %rax
movq 0x8(%rax), %rsi
movq %rbx, %rdi
callq 0xc430
movq %rax, %r15
movq %rax, -0x40(%rbp)
leaq 0x1515c(%rip), %r14     # 0x18348
movq (%r14), %rdi
movq 0x38(%r12), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rdx
leaq 0xd8f7(%rip), %rsi      # 0x10afa
xorl %eax, %eax
callq 0x1100
movq (%r14), %r13
movl 0x1c(%r15), %edi
callq 0x158c
leaq 0xd8ea(%rip), %rsi      # 0x10b07
leaq 0x1514c(%rip), %rdx     # 0x18370
movq %r13, %rdi
movq %rdx, %r13
xorl %eax, %eax
callq 0x1100
movq (%r14), %rdi
leaq 0xd8de(%rip), %rsi      # 0x10b19
movl -0x30(%rbp), %edx
xorl %eax, %eax
callq 0x1100
movq (%r14), %rdi
movq 0x38(%r12), %rax
movq 0x38(%rax), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rdx
leaq 0xd46e(%rip), %rsi      # 0x106ce
xorl %eax, %eax
callq 0x1100
movq (%r14), %rcx
leaq 0xd8b3(%rip), %rdi      # 0x10b24
movl $0xd, %esi
movl $0x1, %edx
callq 0x1170
movq (%r14), %rdi
leaq 0xd8a8(%rip), %rsi      # 0x10b32
movq -0x38(%rbp), %r15
movl %r15d, %edx
xorl %eax, %eax
callq 0x1100
movq 0x38(%r12), %rax
movq 0x38(%rax), %rax
movq 0x38(%rax), %rdi
movq %rbx, %rsi
callq 0x2c96
movq (%r14), %rbx
movq -0x40(%rbp), %r12
movl 0x1c(%r12), %edi
callq 0x158c
leaq 0xd87b(%rip), %rsi      # 0x10b40
movq %rbx, %rdi
movq %r13, %rdx
xorl %eax, %eax
callq 0x1100
leaq 0xd87a(%rip), %rsi      # 0x10b53
movl $0x8, %edi
callq 0x153a
movq (%r14), %rcx
leaq 0xd879(%rip), %rdi      # 0x10b66
movl $0x9, %esi
movl $0x1, %edx
callq 0x1170
movq (%r14), %rbx
movl 0x1c(%r12), %edi
callq 0x158c
leaq 0xd860(%rip), %rsi      # 0x10b70
movq %rbx, %rdi
movq %r13, %rdx
xorl %eax, %eax
callq 0x1100
movq (%r14), %rdi
leaq 0xd85b(%rip), %rsi      # 0x10b82
movl -0x30(%rbp), %edx
xorl %eax, %eax
callq 0x1100
movq (%r14), %rdi
leaq 0xd7de(%rip), %rsi      # 0x10b19
movl %r15d, %edx
jmp 0x340f
movq 0x38(%r14), %r13
movl 0x1500a(%rip), %r14d    # 0x18358
leal 0x1(%r14), %r15d
addl $0x2, %r14d
movl %r14d, 0x14ffb(%rip)    # 0x18358
leaq 0x14fe4(%rip), %r12     # 0x18348
movq (%r12), %rdi
leaq 0xd821(%rip), %rsi      # 0x10b90
movl %r15d, %edx
xorl %eax, %eax
callq 0x1100
movq %r13, %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x1e5b
movq (%r12), %rcx
leaq 0xcf82(%rip), %rdi      # 0x10313
movl $0x9, %esi
movl $0x1, %edx
callq 0x1170
movq (%r12), %rcx
leaq 0xd7f2(%rip), %rdi      # 0x10b9d
movl $0xb, %esi
movl $0x1, %edx
callq 0x1170
leaq 0xd7e8(%rip), %rsi      # 0x10ba9
movl $0xb, %edi
callq 0x153a
movq (%r12), %rdi
leaq 0xd7f1(%rip), %rsi      # 0x10bc7
movl %r14d, %edx
xorl %eax, %eax
callq 0x1100
movq 0x38(%r13), %rdi
movq %rbx, %rsi
callq 0x2c96
movq (%r12), %rdi
leaq 0xd7e0(%rip), %rsi      # 0x10bd7
movl %r15d, %edx
xorl %eax, %eax
callq 0x1100
movq (%r12), %rdi
leaq 0xd784(%rip), %rsi      # 0x10b90
movl %r14d, %edx
xorl %eax, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1100
cmpl $0x4, 0x8(%rbx)
je 0x3671
movq 0x80(%rbx), %rdi
callq 0x3c8f
movq 0x10(%rbx), %rax
cmpq (%r15), %rax
je 0x35a7
movl 0x110(%rbx), %edx
testl %edx, %edx
jle 0x3671
leaq 0x14eec(%rip), %rax     # 0x18348
movq (%rax), %rdi
leaq 0xd613(%rip), %rsi      # 0x10a79
xorl %eax, %eax
callq 0x1100
leaq 0xd614(%rip), %rsi      # 0x10a88
movl $0xa, %edi
jmp 0x365e
xorl %eax, %eax
movslq %eax, %r12
leaq (,%r12,4), %rdi
callq 0x1120
movq %rax, %r13
movq %r14, %rdi
movq %rbx, -0x30(%rbp)
movq %rbx, %rsi
movl %r12d, %edx
movq %rax, %rcx
callq 0x36bc
movl %eax, -0x38(%rbp)
movl 0x14e9e(%rip), %r12d    # 0x18350
incl %r12d
movl %r12d, 0x14e94(%rip)    # 0x18350
testq %r15, %r15
je 0x35f8
leaq 0x14e7c(%rip), %rbx     # 0x18348
movq (%rbx), %rdi
movl (%r13), %edx
leaq 0xd70d(%rip), %rsi      # 0x10be7
xorl %eax, %eax
callq 0x1100
movq %r15, %rdi
movq -0x30(%rbp), %rsi
callq 0x2c96
movq (%rbx), %rdi
leaq 0xd6fd(%rip), %rsi      # 0x10bf4
movl %r12d, %edx
xorl %eax, %eax
callq 0x1100
movq 0x38(%r15), %rax
testq %rax, %rax
je 0x351d
cmpl $0x55, (%rax)
movq 0x38(%rax), %r15
je 0x35bd
movq 0x38(%r15), %r15
jmp 0x3520
xorl %r15d, %r15d
addq $0x4, %r13
jmp 0x34bc
movq %r15, %rdi
movq %rbx, %rsi
callq 0x199b
jmp 0x3585
movq 0x38(%rcx), %rdi
movq %rbx, %rsi
movl $0x1, %edx
callq 0x1e5b
movq 0x30(%r14), %rdi
movq %rbx, %rsi
movl $0x1, %edx
jmp 0x3580
addl $-0x59, %eax
cmpl $-0x2, %eax
jb 0x3569
movq 0x30(%rdi), %rax
cmpq $0x0, 0x38(%rax)
je 0x3680
xorl %r15d, %r15d
movq %rbx, %rsi
xorl %edx, %edx
callq 0x1e5b
movq 0x30(%r14), %rdi
movq %rbx, %rsi
movl %r15d, %edx
callq 0x1b09
leaq 0x14dbc(%rip), %rax     # 0x18348
movq (%rax), %rsi
movl $0xa, %edi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x10e0
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3bc3
leaq 0x14d84(%rip), %rbx     # 0x18348
movq (%rbx), %rdi
leaq 0xd619(%rip), %rsi      # 0x10be7
movl -0x38(%rbp), %edx
xorl %eax, %eax
callq 0x1100
movq %r15, %rdi
movq -0x30(%rbp), %rsi
callq 0x2c96
movq (%rbx), %rdi
leaq 0xd606(%rip), %rsi      # 0x10bf4
movl %r12d, %edx
xorl %eax, %eax
callq 0x1100
movq 0x38(%r14), %rax
movq 0x38(%rax), %rax
movq 0x38(%rax), %rax
movq 0x38(%rax), %r14
leaq 0x14d39(%rip), %rbx     # 0x18348
movq (%rbx), %rdi
leaq 0xd5ce(%rip), %rsi      # 0x10be7
movl %r12d, %edx
xorl %eax, %eax
callq 0x1100
movq 0x20(%r14), %rax
movq 0x80(%rax), %rdi
callq 0x3c8f
movq 0x20(%r14), %rax
movl 0x110(%rax), %edx
testl %edx, %edx
jle 0x3671
movq (%rbx), %rdi
leaq 0xd42f(%rip), %rsi      # 0x10a7a
xorl %eax, %eax
callq 0x1100
leaq 0xd42f(%rip), %rsi      # 0x10a88
movl $0xb, %edi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x153a
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x30(%rdi), %rdi
movl (%rdi), %eax
addl $-0x40, %eax
cmpl $0x31, %eax
ja 0x36b7
movl $0x1, %r15d
movabsq $0x2000000000301, %rcx  # imm = 0x2000000000301
btq %rax, %rcx
jae 0x36b7
movq %rbx, %rsi
movl %r15d, %edx
jmp 0x3571
movq %rax, %rdi
jmp 0x35aa
xorl %r15d, %r15d
jmp 0x36a4