// File: CMU-SAFARI[P]Register-Interval/./src/implementation/RegisterIntervalCreation.cpp
// Function: RegisterIntervalCreationPass::registerIntervalCreationPassOne(std::vector<basicBlock*, std::allocator<basicBlock*>>, int)
vector<registerInterval*> RegisterIntervalCreationPass::registerIntervalCreationPassOne(vector<basicBlock*> BB_vector, int N){ //N is the maximum number of registers allowed in a register-interval 
        basic_blocks = BB_vector;
    
        /* Initialization */
	for (auto b = basic_blocks.begin(); b != basic_blocks.end(); b++){
		(*b)->clear_input_list();
		(*b)->set_registerInterval(nullptr);
	}

	RegisterIntervals.clear();
	for(auto b = basic_blocks.begin(); b != basic_blocks.end(); b++){
		auto Predecessors = (*b)->get_predecessors();
		if(Predecessors.size() == 0){ // each basic block with no predecessors is assumed as an entry basicBlock
			auto temp = new registerInterval();
			RegisterIntervals.push_back(temp);
			(*b)->set_registerInterval(temp);
			WS.push(*b);// The entry basic block is added to the working set of registerInterval creation algorithm
		}
	}

	while (!WS.empty()){
		auto BB = WS.front(); //Get one basic blocks from working set
		WS.pop();
		auto i = BB->RegisterInterval(); //Get the register-interval that this basic block belongs to
		traverse(BB, N); //Traversing the basic block and splitting it if it has more than the allowed number of registers
		if (BB->numberOfRegisters() < N){
                        //In this loop we will add all eligible basic blocks to the current registerInterval (i)
			for (auto b = basic_blocks.begin(); b != basic_blocks.end(); b++){
				set<string> Union;//The set that will contain the union of register sets of all basic blocks of i
                                Union.clear();
				bool C = true;//This boolean determines that the basicBlock is reachable only from the current register-interval (in other words, its all predecessors should belong to the current register-interval)

				visit_all_predecessors(*b);//marks all basic blocks that can reach this basic block

				Union = (*b)->get_output_list();
                                //This loop will add all registers of marked basic blocks that belong to the current register-interval (i)
				for(auto bb = basic_blocks.begin(); bb != basic_blocks.end(); bb++){
					if(mark[(*bb)->getID()]){
						if((*bb)->RegisterInterval() == i){
							auto s = (*bb)->get_output_list();
							for (auto it = s.begin(); it != s.end(); it++){
								Union.insert(*it);
							}
						}
					}
				}
		
				//This loop determines the boolean value of C
				auto P = (*b)->get_predecessors();
                                for(auto p = P.begin(); p != P.end(); p++){
                                        if((*p)->RegisterInterval() != i)
                                                C = false;
                                }

				//If this basic block is eligible, it will be added to the current register-interval
				if ((*b)->RegisterInterval() == nullptr //the basic block should not belong to another register-interval
                                        && C  //All predecessors of the basic block should belong to the current register-interval
                                        && Union.size() < N //The union of all registers of the basic block and current register-interval should not be more than the allowed number
                                        )
                                {
					(*b)->set_registerInterval(i);
					(*b)->set_input_list(Union);
					traverse((*b), N);
				}
			}
		}
                //At this point no more basic blocks can be added to the current register-interval

                set<basicBlock*> Successors; //Successors will contain all successors of the current register-interval (i)
		Successors.clear();
                
                //This loop will add all successors of the current registerInterval to Successors set
		for (auto b = basic_blocks.begin(); b != basic_blocks.end(); b++){
			if ((*b)->RegisterInterval() == i){
				auto S = (*b)->get_successors();
				for (auto s = S.begin(); s != S.end(); s++){
					if ((*s)->RegisterInterval() != i)
						Successors.insert(*s);
				}
			}
		}
                
                //This loop will assign new register-intervals to the successors of the current register-interval
		set<basicBlock*>::iterator it2;
		for (auto s = Successors.begin(); s != Successors.end(); s++){
			if ((*s)->RegisterInterval() == nullptr){
				auto temp = new registerInterval();
				RegisterIntervals.push_back(temp);
				(*s)->set_registerInterval(temp);
				(*s)->clear_input_list();
				WS.push(*s);
			}
		}
	}
        
        /*At this point all register-interval are created
         *      and the rest of the function just sets the register list of register-intervals
         *      and forms the new CFG that its nodes are register-intervals*/

        //This loop will set the register list of all register-intervals
	for (auto i = RegisterIntervals.begin(); i != RegisterIntervals.end(); i++){
                set<string> regList;//the register list of register-interval
		regList.clear();
		for (auto b = basic_blocks.begin(); b != basic_blocks.end(); b++){
			if ((*b)->RegisterInterval() == *i){
				auto s = (*b)->get_output_list();
				for (auto it = s.begin(); it != s.end(); it++){
					regList.insert(*it);
				}
			}
		}
		(*i)->set_register_list(regList);
	}

	//This loop sets the series of instructions of all register-intervals
	string code;
	for (auto i = RegisterIntervals.begin(); i != RegisterIntervals.end(); i++){
		code = "";
		for (auto b = basic_blocks.begin(); b != basic_blocks.end(); b++){
			if ((*b)->RegisterInterval() == *i){
				code = code + (*b)->get_code();
			}
		}
		(*i)->set_code(code);
	}

	//This loop sets the predecessors and successors of all register-intervals
	for (auto i = RegisterIntervals.begin(); i != RegisterIntervals.end(); i++){
		for (auto b = basic_blocks.begin(); b != basic_blocks.end(); b++){
			if ((*b)->RegisterInterval() == *i){
				auto P = (*b)->get_predecessors();
				for (auto p = P.begin(); p != P.end(); p++){
					if ((*p)->RegisterInterval() != *i)
						(*i)->add_predecessor((*p)->RegisterInterval());
				}
                                
                                auto S = (*b)->get_successors();
				for (auto s = S.begin(); s != S.end(); s++){
					if ((*s)->RegisterInterval() != *i)
						(*i)->add_successors((*s)->RegisterInterval());
				}
			}
		}
	}
        
        return RegisterIntervals;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x590, %rsp            # imm = 0x590
movq %rdi, -0x4d0(%rbp)
movq %rdi, %rax
movq %rax, -0x4c8(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
leaq 0x1dbc2(%rip), %rdi     # 0x22290
callq 0xbf30
leaq 0x1dbb6(%rip), %rdi     # 0x22290
callq 0xc1a0
movq %rax, -0x20(%rbp)
leaq 0x1dba6(%rip), %rdi     # 0x22290
callq 0xc210
movq %rax, -0x28(%rbp)
leaq -0x20(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0xc1d0
testb $0x1, %al
jne 0x4706
jmp 0x473d
leaq -0x20(%rbp), %rdi
callq 0xc240
movq (%rax), %rdi
callq 0x4550
leaq -0x20(%rbp), %rdi
callq 0xc240
movq (%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4580
leaq -0x20(%rbp), %rdi
xorl %esi, %esi
callq 0xc310
movq %rax, -0x30(%rbp)
jmp 0x46e3
leaq 0x1db64(%rip), %rdi     # 0x222a8
callq 0xc4d0
leaq 0x1db40(%rip), %rdi     # 0x22290
callq 0xc1a0
movq %rax, -0x38(%rbp)
leaq 0x1db30(%rip), %rdi     # 0x22290
callq 0xc210
movq %rax, -0x40(%rbp)
leaq -0x38(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0xc1d0
testb $0x1, %al
jne 0x477f
jmp 0x4873
leaq -0x38(%rbp), %rdi
callq 0xc240
movq (%rax), %rsi
leaq -0x58(%rbp), %rdi
callq 0x44a0
leaq -0x58(%rbp), %rdi
callq 0xbe80
cmpq $0x0, %rax
jne 0x4848
movl $0xc0, %edi
callq 0x3250
movq %rax, -0x4d8(%rbp)
jmp 0x47ba
movq -0x4d8(%rbp), %rdi
callq 0x3710
jmp 0x47c8
movq -0x4d8(%rbp), %rax
movq %rax, -0x60(%rbp)
leaq 0x1dace(%rip), %rdi     # 0x222a8
leaq -0x60(%rbp), %rsi
callq 0xbc50
jmp 0x47e5
leaq -0x38(%rbp), %rdi
movq %rdi, -0x4e0(%rbp)
callq 0xc240
movq (%rax), %rdi
movq -0x60(%rbp), %rsi
callq 0x4580
movq -0x4e0(%rbp), %rdi
callq 0xc240
movq %rax, %rsi
leaq 0x1daa9(%rip), %rdi     # 0x222c0
callq 0xc4f0
jmp 0x481e
jmp 0x4848
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x4865
movq -0x4d8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
callq 0x3230
jmp 0x4865
leaq -0x58(%rbp), %rdi
callq 0xbdd0
leaq -0x38(%rbp), %rdi
xorl %esi, %esi
callq 0xc310
movq %rax, -0x78(%rbp)
jmp 0x4759
leaq -0x58(%rbp), %rdi
callq 0xbdd0
jmp 0x5852
jmp 0x4875
leaq 0x1da44(%rip), %rdi     # 0x222c0
callq 0xc520
xorb $-0x1, %al
testb $0x1, %al
jne 0x488c
jmp 0x505a
leaq 0x1da2d(%rip), %rdi     # 0x222c0
callq 0xc540
movq (%rax), %rax
movq %rax, -0x80(%rbp)
leaq 0x1da1a(%rip), %rdi     # 0x222c0
callq 0xc560
movq -0x80(%rbp), %rdi
callq 0x4500
movq %rax, -0x88(%rbp)
movq -0x80(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x5860
movq -0x80(%rbp), %rdi
callq 0x4390
cmpl -0x14(%rbp), %eax
jge 0x4d4e
leaq 0x1d9b0(%rip), %rdi     # 0x22290
callq 0xc1a0
movq %rax, -0x90(%rbp)
leaq 0x1d99d(%rip), %rdi     # 0x22290
callq 0xc210
movq %rax, -0x98(%rbp)
leaq -0x90(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0xc1d0
testb $0x1, %al
jne 0x491b
jmp 0x4d4c
leaq -0xc8(%rbp), %rdi
movq %rdi, -0x4e8(%rbp)
callq 0xb630
movq -0x4e8(%rbp), %rdi
callq 0xc460
movb $0x1, -0xc9(%rbp)
leaq -0x90(%rbp), %rdi
callq 0xc240
movq (%rax), %rdi
callq 0x6660
jmp 0x4957
leaq -0x90(%rbp), %rdi
callq 0xc240
movq (%rax), %rsi
leaq -0x100(%rbp), %rdi
callq 0x43c0
jmp 0x4974
leaq -0xc8(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0xc580
leaq -0x100(%rbp), %rdi
callq 0xb6d0
leaq 0x1d8f6(%rip), %rdi     # 0x22290
callq 0xc1a0
movq %rax, -0x108(%rbp)
leaq 0x1d8e3(%rip), %rdi     # 0x22290
callq 0xc210
movq %rax, -0x110(%rbp)
leaq -0x108(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0xc1d0
testb $0x1, %al
jne 0x49d5
jmp 0x4b6f
leaq -0x108(%rbp), %rdi
callq 0xc240
movq (%rax), %rdi
callq 0x4350
movslq %eax, %rsi
leaq 0x1d91d(%rip), %rdi     # 0x22310
callq 0xbb30
movq %rdx, -0x4f8(%rbp)
movq %rax, -0x4f0(%rbp)
jmp 0x4a08
movq -0x4f8(%rbp), %rax
movq -0x4f0(%rbp), %rcx
movq %rcx, -0x120(%rbp)
movq %rax, -0x118(%rbp)
leaq -0x120(%rbp), %rdi
callq 0xc5b0
testb $0x1, %al
jne 0x4a39
jmp 0x4b53
leaq -0x108(%rbp), %rdi
callq 0xc240
movq (%rax), %rdi
callq 0x4500
cmpq -0x88(%rbp), %rax
jne 0x4b51
leaq -0x108(%rbp), %rdi
callq 0xc240
movq (%rax), %rsi
leaq -0x150(%rbp), %rdi
callq 0x43c0
jmp 0x4a77
leaq -0x150(%rbp), %rdi
callq 0xb9f0
movq %rax, -0x158(%rbp)
leaq -0x150(%rbp), %rdi
callq 0xba50
movq %rax, -0x160(%rbp)
leaq -0x158(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0xba20
testb $0x1, %al
jne 0x4ab9
jmp 0x4b45
leaq -0x158(%rbp), %rdi
callq 0xba80
movq %rax, %rsi
leaq -0xc8(%rbp), %rdi
callq 0xbe30
movb %dl, -0x501(%rbp)
movq %rax, -0x500(%rbp)
jmp 0x4ae3
movb -0x501(%rbp), %al
movq -0x500(%rbp), %rcx
movq %rcx, -0x170(%rbp)
movb %al, -0x168(%rbp)
leaq -0x158(%rbp), %rdi
xorl %esi, %esi
callq 0xc5e0
movq %rax, -0x178(%rbp)
jmp 0x4a8a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x4d3b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x150(%rbp), %rdi
callq 0xb6d0
jmp 0x4d3b
leaq -0x150(%rbp), %rdi
callq 0xb6d0
jmp 0x4b53
jmp 0x4b55
leaq -0x108(%rbp), %rdi
xorl %esi, %esi
callq 0xc310
movq %rax, -0x180(%rbp)
jmp 0x49a6
leaq -0x90(%rbp), %rdi
callq 0xc240
movq (%rax), %rsi
leaq -0x198(%rbp), %rdi
callq 0x44a0
jmp 0x4b8c
leaq -0x198(%rbp), %rdi
callq 0xc1a0
movq %rax, -0x1a0(%rbp)
leaq -0x198(%rbp), %rdi
callq 0xc210
movq %rax, -0x1a8(%rbp)
leaq -0x1a0(%rbp), %rdi
leaq -0x1a8(%rbp), %rsi
callq 0xc1d0
testb $0x1, %al
jne 0x4bcb
jmp 0x4c08
leaq -0x1a0(%rbp), %rdi
callq 0xc240
movq (%rax), %rdi
callq 0x4500
cmpq -0x88(%rbp), %rax
je 0x4bef
movb $0x0, -0xc9(%rbp)
jmp 0x4bf1
leaq -0x1a0(%rbp), %rdi
xorl %esi, %esi
callq 0xc310
movq %rax, -0x1b0(%rbp)
jmp 0x4b9f
leaq -0x90(%rbp), %rdi
callq 0xc240
movq (%rax), %rdi
callq 0x4500
cmpq $0x0, %rax
jne 0x4cfd
testb $0x1, -0xc9(%rbp)
je 0x4cfd
leaq -0xc8(%rbp), %rdi
callq 0xc350
movslq -0x14(%rbp), %rcx
cmpq %rcx, %rax
jae 0x4cfd
leaq -0x90(%rbp), %rdi
movq %rdi, -0x518(%rbp)
callq 0xc240
movq (%rax), %rdi
movq -0x88(%rbp), %rsi
callq 0x4580
movq -0x518(%rbp), %rdi
callq 0xc240
movq (%rax), %rax
movq %rax, -0x510(%rbp)
leaq -0x1e0(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0xb710
jmp 0x4c99
movq -0x510(%rbp), %rdi
leaq -0x1e0(%rbp), %rsi
callq 0x4470
jmp 0x4cae
leaq -0x1e0(%rbp), %rdi
callq 0xb6d0
leaq -0x90(%rbp), %rdi
callq 0xc240
movq (%rax), %rdi
movl -0x14(%rbp), %esi
callq 0x5860
jmp 0x4cd3
jmp 0x4cfd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x4d2f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x1e0(%rbp), %rdi
callq 0xb6d0
jmp 0x4d2f
leaq -0x198(%rbp), %rdi
callq 0xbdd0
leaq -0xc8(%rbp), %rdi
callq 0xb6d0
leaq -0x90(%rbp), %rdi
xorl %esi, %esi
callq 0xc310
movq %rax, -0x1e8(%rbp)
jmp 0x48ec
leaq -0x198(%rbp), %rdi
callq 0xbdd0
leaq -0xc8(%rbp), %rdi
callq 0xb6d0
jmp 0x5852
jmp 0x4d4e
leaq -0x218(%rbp), %rdi
callq 0xc620
leaq -0x218(%rbp), %rdi
callq 0xc640
leaq 0x1d523(%rip), %rdi     # 0x22290
callq 0xc1a0
movq %rax, -0x220(%rbp)
leaq 0x1d510(%rip), %rdi     # 0x22290
callq 0xc210
movq %rax, -0x228(%rbp)
leaq -0x220(%rbp), %rdi
leaq -0x228(%rbp), %rsi
callq 0xc1d0
testb $0x1, %al
jne 0x4da8
jmp 0x4efd
leaq -0x220(%rbp), %rdi
callq 0xc240
movq (%rax), %rdi
callq 0x4500
cmpq -0x88(%rbp), %rax
jne 0x4ee1
leaq -0x220(%rbp), %rdi
callq 0xc240
movq (%rax), %rsi
leaq -0x240(%rbp), %rdi
callq 0x44d0
jmp 0x4de6
leaq -0x240(%rbp), %rdi
callq 0xc1a0
movq %rax, -0x248(%rbp)
leaq -0x240(%rbp), %rdi
callq 0xc210
movq %rax, -0x250(%rbp)
leaq -0x248(%rbp), %rdi
leaq -0x250(%rbp), %rsi
callq 0xc1d0
testb $0x1, %al
jne 0x4e28
jmp 0x4ed5
leaq -0x248(%rbp), %rdi
callq 0xc240
movq (%rax), %rdi
callq 0x4500
cmpq -0x88(%rbp), %rax
je 0x4eb9
leaq -0x248(%rbp), %rdi
callq 0xc240
movq %rax, %rsi
leaq -0x218(%rbp), %rdi
callq 0xc660
movb %dl, -0x521(%rbp)
movq %rax, -0x520(%rbp)
jmp 0x4e6f
movb -0x521(%rbp), %al
movq -0x520(%rbp), %rcx
movq %rcx, -0x260(%rbp)
movb %al, -0x258(%rbp)
jmp 0x4eb9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x5049
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x240(%rbp), %rdi
callq 0xbdd0
jmp 0x5049
jmp 0x4ebb
leaq -0x248(%rbp), %rdi
xorl %esi, %esi
callq 0xc310
movq %rax, -0x268(%rbp)
jmp 0x4df9
leaq -0x240(%rbp), %rdi
callq 0xbdd0
jmp 0x4ee3
leaq -0x220(%rbp), %rdi
xorl %esi, %esi
callq 0xc310
movq %rax, -0x270(%rbp)
jmp 0x4d79
leaq -0x278(%rbp), %rdi
callq 0xc6b0
leaq -0x218(%rbp), %rdi
callq 0xc6d0
movq %rax, -0x280(%rbp)
leaq -0x218(%rbp), %rdi
callq 0xc730
movq %rax, -0x288(%rbp)
leaq -0x280(%rbp), %rdi
leaq -0x288(%rbp), %rsi
callq 0xc700
testb $0x1, %al
jne 0x4f4b
jmp 0x5038
leaq -0x280(%rbp), %rdi
callq 0xc760
movq (%rax), %rdi
callq 0x4500
cmpq $0x0, %rax
jne 0x501c
movl $0xc0, %edi
callq 0x3250
movq %rax, -0x530(%rbp)
jmp 0x4f7c
movq -0x530(%rbp), %rdi
callq 0x3710
jmp 0x4f8a
movq -0x530(%rbp), %rax
movq %rax, -0x290(%rbp)
leaq 0x1d309(%rip), %rdi     # 0x222a8
leaq -0x290(%rbp), %rsi
callq 0xbc50
jmp 0x4fad
leaq -0x280(%rbp), %rdi
movq %rdi, -0x538(%rbp)
callq 0xc760
movq (%rax), %rdi
movq -0x290(%rbp), %rsi
callq 0x4580
movq -0x538(%rbp), %rdi
callq 0xc760
movq (%rax), %rdi
callq 0x4550
movq -0x538(%rbp), %rdi
callq 0xc760
movq %rax, %rsi
leaq 0x1d2c7(%rip), %rdi     # 0x222c0
callq 0xc4f0
jmp 0x5000
jmp 0x501c
movq -0x530(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
callq 0x3230
jmp 0x5049
jmp 0x501e
leaq -0x280(%rbp), %rdi
xorl %esi, %esi
callq 0xc780
movq %rax, -0x298(%rbp)
jmp 0x4f1c
leaq -0x218(%rbp), %rdi
callq 0xc7c0
jmp 0x4875
leaq -0x218(%rbp), %rdi
callq 0xc7c0
jmp 0x5852
leaq 0x1d247(%rip), %rdi     # 0x222a8
callq 0xc7e0
movq %rax, -0x2a0(%rbp)
leaq 0x1d234(%rip), %rdi     # 0x222a8
callq 0xc850
movq %rax, -0x2a8(%rbp)
leaq -0x2a0(%rbp), %rdi
leaq -0x2a8(%rbp), %rsi
callq 0xc810
testb $0x1, %al
jne 0x509c
jmp 0x52de
leaq -0x2d8(%rbp), %rdi
callq 0xb630
leaq -0x2d8(%rbp), %rdi
callq 0xc460
leaq 0x1d1d5(%rip), %rdi     # 0x22290
callq 0xc1a0
movq %rax, -0x2e0(%rbp)
leaq 0x1d1c2(%rip), %rdi     # 0x22290
callq 0xc210
movq %rax, -0x2e8(%rbp)
leaq -0x2e0(%rbp), %rdi
leaq -0x2e8(%rbp), %rsi
callq 0xc1d0
testb $0x1, %al
jne 0x50f6
jmp 0x5243
leaq -0x2e0(%rbp), %rdi
callq 0xc240
movq (%rax), %rdi
callq 0x4500
movq %rax, -0x540(%rbp)
leaq -0x2a0(%rbp), %rdi
callq 0xc880
movq %rax, %rcx
movq -0x540(%rbp), %rax
cmpq (%rcx), %rax
jne 0x5227
leaq -0x2e0(%rbp), %rdi
callq 0xc240
movq (%rax), %rsi
leaq -0x318(%rbp), %rdi
callq 0x43c0
jmp 0x514d
leaq -0x318(%rbp), %rdi
callq 0xb9f0
movq %rax, -0x320(%rbp)
leaq -0x318(%rbp), %rdi
callq 0xba50
movq %rax, -0x328(%rbp)
leaq -0x320(%rbp), %rdi
leaq -0x328(%rbp), %rsi
callq 0xba20
testb $0x1, %al
jne 0x518f
jmp 0x521b
leaq -0x320(%rbp), %rdi
callq 0xba80
movq %rax, %rsi
leaq -0x2d8(%rbp), %rdi
callq 0xbe30
movb %dl, -0x549(%rbp)
movq %rax, -0x548(%rbp)
jmp 0x51b9
movb -0x549(%rbp), %al
movq -0x548(%rbp), %rcx
movq %rcx, -0x338(%rbp)
movb %al, -0x330(%rbp)
leaq -0x320(%rbp), %rdi
xorl %esi, %esi
callq 0xc5e0
movq %rax, -0x340(%rbp)
jmp 0x5160
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x52cd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x318(%rbp), %rdi
callq 0xb6d0
jmp 0x52cd
leaq -0x318(%rbp), %rdi
callq 0xb6d0
jmp 0x5229
leaq -0x2e0(%rbp), %rdi
xorl %esi, %esi
callq 0xc310
movq %rax, -0x348(%rbp)
jmp 0x50c7
leaq -0x2a0(%rbp), %rdi
callq 0xc880
movq (%rax), %rax
movq %rax, -0x558(%rbp)
leaq -0x378(%rbp), %rdi
leaq -0x2d8(%rbp), %rsi
callq 0xb710
jmp 0x526e
movq -0x558(%rbp), %rdi
leaq -0x378(%rbp), %rsi
callq 0x3950
jmp 0x5283
leaq -0x378(%rbp), %rdi
callq 0xb6d0
leaq -0x2d8(%rbp), %rdi
callq 0xb6d0
leaq -0x2a0(%rbp), %rdi
xorl %esi, %esi
callq 0xc8a0
movq %rax, -0x380(%rbp)
jmp 0x506d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x378(%rbp), %rdi
callq 0xb6d0
leaq -0x2d8(%rbp), %rdi
callq 0xb6d0
jmp 0x5852
leaq -0x3a0(%rbp), %rdi
callq 0x3360
leaq 0x1cfb7(%rip), %rdi     # 0x222a8
callq 0xc7e0
movq %rax, -0x3a8(%rbp)
leaq 0x1cfa4(%rip), %rdi     # 0x222a8
callq 0xc850
movq %rax, -0x3b0(%rbp)
leaq -0x3a8(%rbp), %rdi
leaq -0x3b0(%rbp), %rsi
callq 0xc810
testb $0x1, %al
jne 0x532c
jmp 0x54f0
leaq 0x12d67(%rip), %rsi     # 0x1809a
leaq -0x3a0(%rbp), %rdi
callq 0x3330
jmp 0x5341
leaq 0x1cf48(%rip), %rdi     # 0x22290
callq 0xc1a0
movq %rax, -0x3b8(%rbp)
leaq 0x1cf35(%rip), %rdi     # 0x22290
callq 0xc210
movq %rax, -0x3c0(%rbp)
leaq -0x3b8(%rbp), %rdi
leaq -0x3c0(%rbp), %rsi
callq 0xc1d0
testb $0x1, %al
jne 0x5383
jmp 0x546d
leaq -0x3b8(%rbp), %rdi
callq 0xc240
movq (%rax), %rdi
callq 0x4500
movq %rax, -0x560(%rbp)
leaq -0x3a8(%rbp), %rdi
callq 0xc880
movq %rax, %rcx
movq -0x560(%rbp), %rax
cmpq (%rcx), %rax
jne 0x5451
leaq -0x3b8(%rbp), %rdi
callq 0xc240
movq (%rax), %rsi
leaq -0x400(%rbp), %rdi
callq 0x4360
jmp 0x53da
leaq -0x3e0(%rbp), %rdi
leaq -0x3a0(%rbp), %rsi
leaq -0x400(%rbp), %rdx
callq 0xc8e0
jmp 0x53f6
leaq -0x3a0(%rbp), %rdi
leaq -0x3e0(%rbp), %rsi
callq 0x32c0
leaq -0x3e0(%rbp), %rdi
callq 0x31a0
leaq -0x400(%rbp), %rdi
callq 0x31a0
jmp 0x5451
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x5846
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x400(%rbp), %rdi
callq 0x31a0
jmp 0x5846
jmp 0x5453
leaq -0x3b8(%rbp), %rdi
xorl %esi, %esi
callq 0xc310
movq %rax, -0x408(%rbp)
jmp 0x5354
leaq -0x3a8(%rbp), %rdi
callq 0xc880
movq (%rax), %rax
movq %rax, -0x568(%rbp)
leaq -0x428(%rbp), %rdi
leaq -0x3a0(%rbp), %rsi
callq 0x3110
jmp 0x5498
movq -0x568(%rbp), %rdi
leaq -0x428(%rbp), %rsi
callq 0x3820
jmp 0x54ad
leaq -0x428(%rbp), %rdi
callq 0x31a0
leaq -0x3a8(%rbp), %rdi
xorl %esi, %esi
callq 0xc8a0
movq %rax, -0x430(%rbp)
jmp 0x52fd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x428(%rbp), %rdi
callq 0x31a0
jmp 0x5846
leaq 0x1cdb1(%rip), %rdi     # 0x222a8
callq 0xc7e0
movq %rax, -0x438(%rbp)
leaq 0x1cd9e(%rip), %rdi     # 0x222a8
callq 0xc850
movq %rax, -0x440(%rbp)
leaq -0x438(%rbp), %rdi
leaq -0x440(%rbp), %rsi
callq 0xc810
testb $0x1, %al
jne 0x5532
jmp 0x5815
leaq 0x1cd57(%rip), %rdi     # 0x22290
callq 0xc1a0
movq %rax, -0x448(%rbp)
leaq 0x1cd44(%rip), %rdi     # 0x22290
callq 0xc210
movq %rax, -0x450(%rbp)
leaq -0x448(%rbp), %rdi
leaq -0x450(%rbp), %rsi
callq 0xc1d0
testb $0x1, %al
jne 0x5574
jmp 0x57f9
leaq -0x448(%rbp), %rdi
callq 0xc240
movq (%rax), %rdi
callq 0x4500
movq %rax, -0x570(%rbp)
leaq -0x438(%rbp), %rdi
callq 0xc880
movq %rax, %rcx
movq -0x570(%rbp), %rax
cmpq (%rcx), %rax
jne 0x57dd
leaq -0x448(%rbp), %rdi
callq 0xc240
movq (%rax), %rsi
leaq -0x468(%rbp), %rdi
callq 0x44a0
jmp 0x55cb
leaq -0x468(%rbp), %rdi
callq 0xc1a0
movq %rax, -0x470(%rbp)
leaq -0x468(%rbp), %rdi
callq 0xc210
movq %rax, -0x478(%rbp)
leaq -0x470(%rbp), %rdi
leaq -0x478(%rbp), %rsi
callq 0xc1d0
testb $0x1, %al
jne 0x560d
jmp 0x56ad
leaq -0x470(%rbp), %rdi
callq 0xc240
movq (%rax), %rdi
callq 0x4500
movq %rax, -0x578(%rbp)
leaq -0x438(%rbp), %rdi
callq 0xc880
movq %rax, %rcx
movq -0x578(%rbp), %rax
cmpq (%rcx), %rax
je 0x5691
leaq -0x438(%rbp), %rdi
callq 0xc880
movq (%rax), %rax
movq %rax, -0x580(%rbp)
leaq -0x470(%rbp), %rdi
callq 0xc240
movq (%rax), %rdi
callq 0x4500
movq -0x580(%rbp), %rdi
movq %rax, %rsi
callq 0x3b10
jmp 0x567e
jmp 0x5691
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x57cf
jmp 0x5693
leaq -0x470(%rbp), %rdi
xorl %esi, %esi
callq 0xc310
movq %rax, -0x480(%rbp)
jmp 0x55de
leaq -0x448(%rbp), %rdi
callq 0xc240
movq (%rax), %rsi
leaq -0x498(%rbp), %rdi
callq 0x44d0
jmp 0x56ca
leaq -0x498(%rbp), %rdi
callq 0xc1a0
movq %rax, -0x4a0(%rbp)
leaq -0x498(%rbp), %rdi
callq 0xc210
movq %rax, -0x4a8(%rbp)
leaq -0x4a0(%rbp), %rdi
leaq -0x4a8(%rbp), %rsi
callq 0xc1d0
testb $0x1, %al
jne 0x570c
jmp 0x57b5
leaq -0x4a0(%rbp), %rdi
callq 0xc240
movq (%rax), %rdi
callq 0x4500
movq %rax, -0x588(%rbp)
leaq -0x438(%rbp), %rdi
callq 0xc880
movq %rax, %rcx
movq -0x588(%rbp), %rax
cmpq (%rcx), %rax
je 0x5799
leaq -0x438(%rbp), %rdi
callq 0xc880
movq (%rax), %rax
movq %rax, -0x590(%rbp)
leaq -0x4a0(%rbp), %rdi
callq 0xc240
movq (%rax), %rdi
callq 0x4500
movq -0x590(%rbp), %rdi
movq %rax, %rsi
callq 0x3bb0
jmp 0x577d
jmp 0x5799
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x498(%rbp), %rdi
callq 0xbdd0
jmp 0x57cf
jmp 0x579b
leaq -0x4a0(%rbp), %rdi
xorl %esi, %esi
callq 0xc310
movq %rax, -0x4b0(%rbp)
jmp 0x56dd
leaq -0x498(%rbp), %rdi
callq 0xbdd0
leaq -0x468(%rbp), %rdi
callq 0xbdd0
jmp 0x57dd
leaq -0x468(%rbp), %rdi
callq 0xbdd0
jmp 0x5846
jmp 0x57df
leaq -0x448(%rbp), %rdi
xorl %esi, %esi
callq 0xc310
movq %rax, -0x4b8(%rbp)
jmp 0x5545
jmp 0x57fb
leaq -0x438(%rbp), %rdi
xorl %esi, %esi
callq 0xc8a0
movq %rax, -0x4c0(%rbp)
jmp 0x5503
movq -0x4d0(%rbp), %rdi
leaq 0x1ca85(%rip), %rsi     # 0x222a8
callq 0xbcc0
jmp 0x582a
leaq -0x3a0(%rbp), %rdi
callq 0x31a0
movq -0x4c8(%rbp), %rax
addq $0x590, %rsp            # imm = 0x590
popq %rbp
retq
leaq -0x3a0(%rbp), %rdi
callq 0x31a0
movq -0x68(%rbp), %rdi
callq 0x3440
nopl (%rax,%rax)