// File: /workspace/github_cpp_makefile_star2_O1/sangwoojun[P]rv32emulator/emulator.cpp
// Function: execute(unsigned char*, instr*, label_loc*, int, bool)
void execute(uint8_t* mem, instr* imem, label_loc* labels, int label_count, bool start_immediate) {
	uint32_t rf[32];
	uint32_t rf_mirror[32];
	uint32_t pc = 0;
	uint32_t inst_cnt = 0;
	for ( int i = 0; i < 32; i++ ) {
		rf[i] = 0;
		rf_mirror[i] = 0;
	}

	bool stepping = !start_immediate;
	int stepcnt = 0;
	char keybuf[128];
	char* kbp = keybuf;


	bool dexit = false;
	while(!dexit) {
		uint32_t iid = pc/4;
		instr i = imem[iid];
		inst_cnt ++;

		if ( stepping || i.breakpoint ) {
			if ( stepcnt > 0 ) {
				stepcnt -= 1;
			} 

			if ( stepcnt == 0 || i.breakpoint ) {
				stepping = true;
				printf( "\n" );
				if ( i.psrc ) printf( "Next: %s\n", i.psrc );
				while (true) {
					printf( "[inst: %6d pc: %6d, src line %4d]\n", inst_cnt, pc, i.orig_line );

					std::string linebuf;
					fflush(stdout);
					linenoise::Readline(">>", linebuf);
					memcpy(keybuf, linebuf.c_str(), 128);
					linenoise::AddHistory(linebuf.c_str());
					//while ((kbp = linenoise?::Readline(">>")) == NULL);
					//fgets(keybuf, 128, stdin);


					for ( int i = 0; i < strlen(keybuf); i++ ) if (keybuf[i] == '\n') keybuf[i] = '\0';

					if ( keybuf[0] == 'q' ) {
						printf( "Quit command input! Exiting...\n" );
						exit(0);
					}
					if ( keybuf[0] == 'c' ) {
						stepping = false;
						break;
					}
					if ( strlen(keybuf) == 0 ) {
						break;
					}
					if ( keybuf[0] == 's' ) {
						stepcnt = parse_imm(keybuf+1, 16, 0, false);
						break;
					}
					if ( keybuf[0] == 'b' ) { // todo breakpoint!
						uint32_t break_line = parse_imm(keybuf+1, 16, 0, false);
						if ( strlen(keybuf+1) == 0 ) {
							for ( int i = 0; i < DATA_OFFSET/4; i++ ) {
								if ( imem[i].breakpoint ) printf( "Break at line %d: %s\n", imem[i].orig_line, imem[i].psrc );
							}
						} else {
							for ( int i = 0; i < DATA_OFFSET/4; i++ ) {
								if ( imem[i].orig_line >= break_line ) {
									printf( "Break point added to line %d\n", break_line );
									imem[i].breakpoint = true;
									break;
								}
							}
						}
					}
					if ( keybuf[0] == 'B' ) { // breakpoint remove
						uint32_t break_line = parse_imm(keybuf+1, 16, 0, false);
						for ( int i = 0; i < DATA_OFFSET/4; i++ ) {
							if ( imem[i].orig_line == break_line && imem[i].breakpoint ) {
								printf( "Break point removed from line %d\n", break_line );
								imem[i].breakpoint = false;
								break;
							}
						}
					}
					if ( keybuf[0] == 'r' ) {
						int reg = parse_reg(keybuf+1, 0, false);
						if ( reg >= 0 ) printf( "rf[%2d] = 0x%x\n", reg, rf[reg] );
						if ( reg < 0 ) print_regfile(rf);
					}
					if ( keybuf[0] == 'm' ) {
						uint32_t addr = parse_imm(keybuf+1, 31, 0, false); // just for simplicity
						int cnt = 1;
						char* ftok = strtok(keybuf, " \t\r\n");
						ftok = strtok(NULL, " \t\r\n");
						if ( ftok ) {
							cnt = parse_imm(ftok, 16, 0, false);
						}

						for ( int w = 0; w < cnt; w++ ) {
							printf( "0x%04x: ", addr+(w*4) );
							for ( int i = 0; i < 4; i++ ) {
								printf( "%02x ", mem[addr+(w*4)+i] );
							}
							printf( "\n" );
						}
					}
					if ( keybuf[0] == 'l' ) {
						printf( "Listing compiled isntructions\n" );
						printf( " srcline : Compiled instruction\n" );
						for ( int i = 0; i < DATA_OFFSET/4; i++ ) {
							instr* ii = &imem[i];
							if ( ii->orig_line >= 0 && ii->psrc ) {
								printf( "%9d: %s\n", ii->orig_line, ii->psrc );
							}
						}
					}
				}
			}
		}
		
		int pc_next = pc + 4;
		switch (i.op) {
			case ADD: rf[i.a1.reg] = rf[i.a2.reg] + rf[i.a3.reg]; break;
			case SUB: rf[i.a1.reg] = rf[i.a2.reg] - rf[i.a3.reg]; break;
			case SLT: rf[i.a1.reg] = (*(int32_t*)&rf[i.a2.reg]) < (*(int32_t*)&rf[i.a3.reg]) ? 1 : 0; break;
			case SLTU: rf[i.a1.reg] = rf[i.a2.reg] + rf[i.a3.reg]; break;
			case AND: rf[i.a1.reg] = rf[i.a2.reg] & rf[i.a3.reg]; break;
			case OR: rf[i.a1.reg] = rf[i.a2.reg] | rf[i.a3.reg]; break;
			case XOR: rf[i.a1.reg] = rf[i.a2.reg] ^ rf[i.a3.reg]; break;
			case SLL: rf[i.a1.reg] = rf[i.a2.reg] << rf[i.a3.reg]; break;
			case SRL: rf[i.a1.reg] = rf[i.a2.reg] >> rf[i.a3.reg]; break;
			case SRA: rf[i.a1.reg] = (*(int32_t*)&rf[i.a2.reg]) >> rf[i.a3.reg]; break;


			case ADDI: rf[i.a1.reg] = rf[i.a2.reg] + i.a3.imm; break;
			case SLTI: rf[i.a1.reg] = (*(int32_t*)&rf[i.a2.reg]) < (*(int32_t*)&(i.a3.imm)) ? 1 : 0; break;
			case SLTIU: rf[i.a1.reg] = rf[i.a2.reg] < i.a3.imm ? 1 : 0; break;
			case ANDI: rf[i.a1.reg] = rf[i.a2.reg] & i.a3.imm; break;
			case ORI: rf[i.a1.reg] = rf[i.a2.reg] | i.a3.imm; break;
			case XORI: rf[i.a1.reg] = rf[i.a2.reg] ^ i.a3.imm; break;
			case SLLI: rf[i.a1.reg] = rf[i.a2.reg] << i.a3.imm; break;
			case SRLI: rf[i.a1.reg] = rf[i.a2.reg] >> i.a3.imm; break;
			case SRAI: rf[i.a1.reg] = (*(int32_t*)&rf[i.a2.reg]) >> i.a3.imm; break;

			case LB:
			case LBU: 
			case LH:
			case LHU:
			case LW: rf[i.a1.reg] = mem_read(mem, rf[i.a2.reg]+i.a3.imm, i.op); break;
			
			case SB: 
			case SH: 
			case SW: mem_write(mem, rf[i.a2.reg]+i.a3.imm, rf[i.a1.reg], i.op); break;
			/*

			case SB: mem[rf[i.a2.reg]+i.a3.imm] = *(uint8_t*)&(rf[i.a1.reg]); break;
			case SH: *(uint16_t*)&(mem[rf[i.a2.reg]+i.a3.imm]) = *(uint16_t*)&(rf[i.a1.reg]); break;
			case SW: 
				*(uint32_t*)&(mem[rf[i.a2.reg]+i.a3.imm]) = rf[i.a1.reg]; 
				//printf( "Writing %x to addr %x\n", rf[i.a1.reg], rf[i.a2.reg]+i.a3.imm );
			break;
			*/

			case BEQ: if ( rf[i.a1.reg] == rf[i.a2.reg] ) pc_next = i.a3.imm; break;
			case BGE: if ( *(int32_t*)&rf[i.a1.reg] >= *(int32_t*)&rf[i.a2.reg] ) pc_next = i.a3.imm; break;
			case BGEU: if ( rf[i.a1.reg] >= rf[i.a2.reg] ) pc_next = i.a3.imm; 
				break;
			case BLT: if ( *(int32_t*)&rf[i.a1.reg] < *(int32_t*)&rf[i.a2.reg] ) pc_next = i.a3.imm; break;
			case BLTU: if ( rf[i.a1.reg] < rf[i.a2.reg] ) pc_next = i.a3.imm; break;
			case BNE: if ( rf[i.a1.reg] != rf[i.a2.reg] ) pc_next = i.a3.imm; break;

			case JAL:
				rf[i.a1.reg] = pc + 4;
				pc_next = i.a2.imm;
				//printf( "jal %d %x\n", pc+4, pc_next );
				break;
			case JALR:
				rf[i.a1.reg] = pc + 4;
				pc_next = rf[i.a2.reg] + i.a3.imm;
				//printf( "jalr %d %d(%d)\n", i.a1.reg, i.a3.imm, i.a2.reg );
				break;
			case AUIPC:
				rf[i.a1.reg] = pc + (i.a2.imm<<12);
				//printf( "auipc %x \n", rf[i.a1.reg] );
				break;
			case LUI:
				rf[i.a1.reg] = (i.a2.imm<<12);
				//printf( "lui %x \n", rf[i.a1.reg] );
				break;
			
			case HCF:
				printf( "\n\n----------\n\n" );
				printf( "Reached Halt and Catch Fire instruction!\n" );
				printf( "inst: %6d pc: %6d src line: %d\n", inst_cnt, pc, i.orig_line );
				print_regfile(rf);
				printf( "Cache read %d/%d Cache write %d/%d\n", cache_read_hits, mem_read_reqs, cache_write_hits, mem_write_reqs );
				printf( "Cache flush words: %d\n", mem_flush_words);
				dexit = true;
				break;
			case UNIMPL:
			default:
				printf( "Reached an unimplemented instruction!\n" );
				if ( i.psrc ) printf( "Instruction: %s\n", i.psrc );
				printf( "inst: %6d pc: %6d src line: %d\n", inst_cnt, pc, i.orig_line );
				print_regfile(rf);
				dexit = true;
				break;
		}
		pc = pc_next % MEM_BYTES;
		rf[0] = 0;// cleaner way to do this?
		if ( stepping ) {
			for ( int i = 0; i < 32; i++ ) {
				if ( rf[i] != rf_mirror[i] ) printf( ">> rf[x%02d] %x -> %x\n", i, rf_mirror[i], rf[i] );
				rf_mirror[i] = rf[i];
			}
		}

		//printf( "reg dst %d -> %x %d\n", i.a1.reg, rf[i.a1.reg], rf[i.a1.reg] );

		fflush(stdout);
		
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x248, %rsp            # imm = 0x248
movq %rsi, -0x50(%rbp)
movq %rdi, -0x110(%rbp)
xorps %xmm0, %xmm0
leaq -0xf0(%rbp), %rax
movaps %xmm0, (%rax)
movaps %xmm0, 0x10(%rax)
movaps %xmm0, 0x20(%rax)
movaps %xmm0, 0x30(%rax)
movaps %xmm0, 0x40(%rax)
movaps %xmm0, 0x50(%rax)
movaps %xmm0, 0x60(%rax)
movaps %xmm0, 0x70(%rax)
movaps %xmm0, -0x270(%rbp)
movaps %xmm0, -0x260(%rbp)
movaps %xmm0, -0x250(%rbp)
movaps %xmm0, -0x240(%rbp)
movaps %xmm0, -0x230(%rbp)
movaps %xmm0, -0x220(%rbp)
movaps %xmm0, -0x210(%rbp)
movaps %xmm0, -0x200(%rbp)
xorb $0x1, %r8b
movl %r8d, -0x54(%rbp)
leaq -0x128(%rbp), %r12
leaq -0x1f0(%rbp), %r15
xorl %ebx, %ebx
movl $0x0, -0x58(%rbp)
movl $0x0, -0x60(%rbp)
movq $0x0, -0xf8(%rbp)
movq -0x110(%rbp), %r13
movl %ebx, %eax
shrl $0x2, %eax
imulq $0x98, %rax, %rax
movq -0x50(%rbp), %rcx
movl (%rcx,%rax), %edx
movq %rdx, -0x140(%rbp)
movl 0x58(%rcx,%rax), %edx
movl %edx, -0x5c(%rbp)
movslq 0x28(%rcx,%rax), %rdx
movslq 0x54(%rcx,%rax), %rdi
movslq 0x80(%rcx,%rax), %rsi
movq %rsi, -0x48(%rbp)
movl 0x84(%rcx,%rax), %esi
movq 0x88(%rcx,%rax), %r8
movq %r8, -0x108(%rbp)
movl 0x90(%rcx,%rax), %r8d
movl %r8d, -0x64(%rbp)
movb 0x94(%rcx,%rax), %al
incl -0x58(%rbp)
testb $0x1, -0x54(%rbp)
movq %rdx, -0x38(%rbp)
movl %esi, -0x2c(%rbp)
movq %rdi, -0x40(%rbp)
jne 0x4a13
testb $0x1, %al
je 0x4f1b
xorl %ecx, %ecx
movl -0x60(%rbp), %edx
testl %edx, %edx
setg %cl
subl %ecx, %edx
movl %edx, -0x60(%rbp)
je 0x4a2c
testb $0x1, %al
je 0x4f1b
movl $0xa, %edi
callq 0x2270
movq -0x108(%rbp), %rsi
testq %rsi, %rsi
je 0x4a50
leaq 0x6e46(%rip), %rdi      # 0xb88f
xorl %eax, %eax
callq 0x2040
movb $0x1, %al
movl %eax, -0x54(%rbp)
movq %rbx, -0x148(%rbp)
leaq 0x6e36(%rip), %rdi      # 0xb899
movl -0x58(%rbp), %esi
movl %ebx, %edx
movl -0x64(%rbp), %ecx
xorl %eax, %eax
callq 0x2040
movq %r12, -0x138(%rbp)
movq $0x0, -0x130(%rbp)
movb $0x0, -0x128(%rbp)
movq 0x951e(%rip), %rax      # 0xdfb0
movq (%rax), %rdi
callq 0x21f0
leaq 0x6f44(%rip), %rdi      # 0xb9e5
callq 0x2220
testq %rax, %rax
je 0x4ae0
movq %rax, %rbx
xorl %r15d, %r15d
leaq 0x92c8(%rip), %rax      # 0xdd80
movq (%r15,%rax), %rsi
movq %rbx, %rdi
callq 0x21d0
testl %eax, %eax
je 0x4ad5
leaq 0x8(%r15), %rcx
cmpq $0x10, %r15
movq %rcx, %r15
jne 0x4ab1
testl %eax, %eax
leaq -0x1f0(%rbp), %r15
je 0x4af5
leaq 0x6dd5(%rip), %rdi      # 0xb8bc
leaq -0x138(%rbp), %rsi
callq 0x5824
jmp 0x4b4a
leaq 0x6bf3(%rip), %rdi      # 0xb6ef
leaq 0x6db9(%rip), %rsi      # 0xb8bc
xorl %eax, %eax
callq 0x2040
movq 0x949f(%rip), %rax      # 0xdfb0
movq (%rax), %rdi
callq 0x21f0
movq 0x94b8(%rip), %rcx      # 0xdfd8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x2190
movsbl %al, %edx
movq 0x949a(%rip), %rdi      # 0xdfd8
leaq -0x138(%rbp), %rsi
callq 0x2390
movq -0x138(%rbp), %rbx
movl $0x80, %edx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x2150
movq 0x9fc8(%rip), %rdi      # 0xeb30
cmpq %rdi, 0x9fb9(%rip)      # 0xeb28
je 0x4b81
addq $-0x20, %rdi
movq %rbx, %rsi
callq 0x2080
testl %eax, %eax
je 0x4be4
movq 0x9fa8(%rip), %rax      # 0xeb30
movq 0x9f99(%rip), %rsi      # 0xeb28
subq %rsi, %rax
cmpq $0xc80, %rax            # imm = 0xC80
jne 0x4ba6
leaq 0x9f87(%rip), %rdi      # 0xeb28
callq 0x6e7c
leaq -0x168(%rbp), %rdi
movq %rbx, %rsi
leaq -0x65(%rbp), %rdx
callq 0x20d0
leaq 0x9f68(%rip), %rdi      # 0xeb28
leaq -0x168(%rbp), %rsi
callq 0x6eee
movq -0x168(%rbp), %rdi
leaq -0x158(%rbp), %rax
cmpq %rax, %rdi
je 0x4be4
callq 0x2180
cmpb $0x0, -0x1f0(%rbp)
je 0x4c19
xorl %ebx, %ebx
cmpb $0xa, -0x1f0(%rbp,%rbx)
jne 0x4c01
movb $0x0, -0x1f0(%rbp,%rbx)
incq %rbx
movq %r15, %rdi
callq 0x20f0
cmpq %rbx, %rax
ja 0x4bef
testq %rax, %rax
sete %cl
jmp 0x4c1b
movb $0x1, %cl
movzbl -0x1f0(%rbp), %eax
xorl %ebx, %ebx
cmpl $0x63, %eax
je 0x4c3d
cmpl $0x71, %eax
je 0x53c3
testb %cl, %cl
je 0x4c49
xorl %ebx, %ebx
jmp 0x4efb
movl $0x0, -0x54(%rbp)
jmp 0x4efb
cmpl $0x62, %eax
je 0x4c76
cmpl $0x73, %eax
jne 0x4d09
xorl %ebx, %ebx
leaq -0x1ef(%rbp), %rdi
movl $0x10, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x3173
movl %eax, -0x60(%rbp)
jmp 0x4efb
leaq -0x1ef(%rbp), %rdi
movl $0x10, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x3173
cmpb $0x0, -0x1ef(%rbp)
je 0x4cb5
movl $0x94, %ebx
movq -0x50(%rbp), %rcx
cmpl %eax, -0x4(%rcx,%rbx)
jae 0x4cf1
addq $0x98, %rbx
cmpq $0x130094, %rbx         # imm = 0x130094
jne 0x4c9d
jmp 0x4d09
movl $0x94, %ebx
movq -0x50(%rbp), %rax
cmpb $0x1, (%rax,%rbx)
jne 0x4cdf
movl -0x4(%rax,%rbx), %esi
movq -0xc(%rax,%rbx), %rdx
leaq 0x6beb(%rip), %rdi      # 0xb8bf
xorl %eax, %eax
callq 0x2040
movq -0x50(%rbp), %rax
addq $0x98, %rbx
cmpq $0x130094, %rbx         # imm = 0x130094
jne 0x4cbe
jmp 0x4d09
leaq 0x6bdd(%rip), %rdi      # 0xb8d5
movl %eax, %esi
xorl %eax, %eax
callq 0x2040
movq -0x50(%rbp), %rax
movb $0x1, (%rax,%rbx)
cmpb $0x42, -0x1f0(%rbp)
jne 0x4d66
leaq -0x1ef(%rbp), %rdi
movl $0x10, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x3173
movq -0x50(%rbp), %rcx
movl $0x94, %ebx
cmpl %eax, -0x4(%rcx,%rbx)
jne 0x4d3c
cmpb $0x1, (%rcx,%rbx)
je 0x4d4e
addq $0x98, %rbx
cmpq $0x130094, %rbx         # imm = 0x130094
jne 0x4d30
jmp 0x4d66
leaq 0x6b9e(%rip), %rdi      # 0xb8f3
movl %eax, %esi
xorl %eax, %eax
callq 0x2040
movq -0x50(%rbp), %rax
movb $0x0, (%rax,%rbx)
cmpb $0x72, -0x1f0(%rbp)
jne 0x4dae
leaq -0x1ef(%rbp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2d17
movl %eax, %ebx
testl %eax, %eax
js 0x4d9e
movl %ebx, %eax
movl -0xf0(%rbp,%rax,4), %edx
leaq 0x6b80(%rip), %rdi      # 0xb915
movl %ebx, %esi
xorl %eax, %eax
callq 0x2040
testl %ebx, %ebx
jns 0x4dae
leaq -0xf0(%rbp), %rdi
callq 0x2814
cmpb $0x6d, -0x1f0(%rbp)
jne 0x4e83
leaq -0x1ef(%rbp), %rdi
movl $0x1f, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x3173
movq %rax, -0x118(%rbp)
leaq -0x1f0(%rbp), %rdi
leaq 0x691d(%rip), %rbx      # 0xb702
movq %rbx, %rsi
callq 0x2320
xorl %edi, %edi
movq %rbx, %rsi
callq 0x2320
testq %rax, %rax
je 0x4e0f
movq %rax, %rdi
movl $0x10, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x3173
jmp 0x4e14
movl $0x1, %eax
testl %eax, %eax
jle 0x4e83
movl -0x118(%rbp), %r15d
xorl %r12d, %r12d
movl %eax, -0xfc(%rbp)
movq -0x118(%rbp), %rax
leal (%rax,%r12,4), %esi
leaq 0x6aeb(%rip), %rdi      # 0xb925
xorl %eax, %eax
callq 0x2040
xorl %ebx, %ebx
leaq 0x6ae4(%rip), %r14      # 0xb92e
leal (%r15,%rbx), %eax
movzbl (%r13,%rax), %esi
movq %r14, %rdi
xorl %eax, %eax
callq 0x2040
incq %rbx
cmpq $0x4, %rbx
jne 0x4e4a
movl $0xa, %edi
callq 0x2270
incl %r12d
addq $0x4, %r15
movl -0xfc(%rbp), %eax
cmpl %eax, %r12d
jne 0x4e28
movb $0x1, %bl
cmpb $0x6c, -0x1f0(%rbp)
jne 0x4eed
leaq 0x6bed(%rip), %rdi      # 0xba82
callq 0x22e0
leaq 0x6bff(%rip), %rdi      # 0xbaa0
callq 0x22e0
movl $0x90, %r15d
leaq -0x128(%rbp), %r12
movq -0x50(%rbp), %rax
movl (%rax,%r15), %esi
testl %esi, %esi
js 0x4edb
movq -0x8(%rax,%r15), %rdx
testq %rdx, %rdx
je 0x4edb
leaq 0x6a64(%rip), %rdi      # 0xb934
xorl %eax, %eax
callq 0x2040
movq -0x50(%rbp), %rax
addq $0x98, %r15
cmpq $0x130090, %r15         # imm = 0x130090
jne 0x4eb7
jmp 0x4ef4
leaq -0x128(%rbp), %r12
leaq -0x1f0(%rbp), %r15
movq -0x138(%rbp), %rdi
cmpq %r12, %rdi
je 0x4f0c
callq 0x2180
testb %bl, %bl
movq -0x148(%rbp), %rbx
jne 0x4a5c
leal 0x4(%rbx), %r12d
movq -0x140(%rbp), %r8
leal -0x1(%r8), %eax
cmpl $0x25, %eax
ja 0x535b
leaq 0x31aa(%rip), %rcx      # 0x80e4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
movq -0x110(%rbp), %rdi
jmpq *%rax
movl -0x2c(%rbp), %esi
movq -0x40(%rbp), %rax
addl -0xf0(%rbp,%rax,4), %esi
movl %r8d, %edx
callq 0x336c
jmp 0x52bd
movl -0x2c(%rbp), %esi
movq -0x40(%rbp), %rax
addl -0xf0(%rbp,%rax,4), %esi
movq -0x38(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %edx
movl %r8d, %ecx
callq 0x327e
jmp 0x52c8
movq -0x48(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
addl -0xf0(%rbp,%rcx,4), %eax
jmp 0x52bd
leaq 0x6b13(%rip), %rdi      # 0xbac0
callq 0x22e0
leaq 0x6b15(%rip), %rdi      # 0xbace
callq 0x22e0
leaq 0x6978(%rip), %rdi      # 0xb93d
movl -0x58(%rbp), %esi
movl %ebx, %edx
movl -0x64(%rbp), %ecx
xorl %eax, %eax
callq 0x2040
leaq -0xf0(%rbp), %rdi
callq 0x2814
movl 0x9b6a(%rip), %esi      # 0xeb50
movl 0x9b60(%rip), %edx      # 0xeb4c
movl 0x9b56(%rip), %ecx      # 0xeb48
movl 0x9b4b(%rip), %r8d      # 0xeb44
leaq 0x695d(%rip), %rdi      # 0xb95d
xorl %eax, %eax
callq 0x2040
movl 0x9b33(%rip), %esi      # 0xeb40
leaq 0x696d(%rip), %rdi      # 0xb981
xorl %eax, %eax
callq 0x2040
jmp 0x53a3
movq -0x48(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
xorl -0xf0(%rbp,%rcx,4), %eax
jmp 0x52bd
movl -0x2c(%rbp), %ecx
movq -0x40(%rbp), %rax
xorl -0xf0(%rbp,%rax,4), %ecx
jmp 0x5254
movq -0x40(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movl -0x2c(%rbp), %ecx
jmp 0x51b2
movq -0x40(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
xorl %ecx, %ecx
movq -0x48(%rbp), %rdx
cmpl -0xf0(%rbp,%rdx,4), %eax
setl %cl
jmp 0x5254
movl -0x5c(%rbp), %ecx
shll $0xc, %ecx
jmp 0x5254
movq -0x40(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x48(%rbp), %rcx
subl -0xf0(%rbp,%rcx,4), %eax
jmp 0x52bd
movq -0x40(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movl -0x2c(%rbp), %ecx
jmp 0x5291
movq -0x38(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
cmpl -0xf0(%rbp,%rcx,4), %eax
movl -0x2c(%rbp), %eax
cmovel %r12d, %eax
jmp 0x5216
movl -0x2c(%rbp), %ecx
movq -0x40(%rbp), %rax
andl -0xf0(%rbp,%rax,4), %ecx
jmp 0x5254
movq -0x38(%rbp), %rax
movl %r12d, -0xf0(%rbp,%rax,4)
movl -0x5c(%rbp), %eax
jmp 0x5216
movq -0x38(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
cmpl -0xf0(%rbp,%rcx,4), %eax
cmovll -0x2c(%rbp), %r12d
jmp 0x52c8
movl -0x2c(%rbp), %ecx
movq -0x40(%rbp), %rax
addl -0xf0(%rbp,%rax,4), %ecx
jmp 0x5254
movq -0x48(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
andl -0xf0(%rbp,%rcx,4), %eax
jmp 0x52bd
movq -0x38(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
cmpl -0xf0(%rbp,%rcx,4), %eax
movl -0x2c(%rbp), %eax
cmovll %r12d, %eax
jmp 0x5216
movl -0x5c(%rbp), %ecx
shll $0xc, %ecx
addl %ebx, %ecx
jmp 0x5254
movq -0x38(%rbp), %rax
movl %r12d, -0xf0(%rbp,%rax,4)
movl -0x2c(%rbp), %eax
movq -0x40(%rbp), %rcx
addl -0xf0(%rbp,%rcx,4), %eax
jmp 0x5216
movq -0x40(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x48(%rbp), %rcx
movb -0xf0(%rbp,%rcx,4), %cl
shll %cl, %eax
jmp 0x52bd
movq -0x38(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
cmpl -0xf0(%rbp,%rcx,4), %eax
cmovel -0x2c(%rbp), %r12d
jmp 0x52c8
movq -0x38(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
cmpl -0xf0(%rbp,%rcx,4), %eax
cmovbl -0x2c(%rbp), %r12d
jmp 0x52c8
movq -0x38(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
cmpl -0xf0(%rbp,%rcx,4), %eax
movl -0x2c(%rbp), %eax
cmovbl %r12d, %eax
movl %eax, %r12d
jmp 0x52c8
movq -0x40(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movl -0x2c(%rbp), %ecx
jmp 0x5277
movq -0x48(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
orl -0xf0(%rbp,%rcx,4), %eax
jmp 0x52bd
movl -0x2c(%rbp), %ecx
movq -0x40(%rbp), %rax
orl -0xf0(%rbp,%rax,4), %ecx
movq -0x38(%rbp), %rax
movl %ecx, -0xf0(%rbp,%rax,4)
jmp 0x52c8
movq -0x40(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x48(%rbp), %rcx
movb -0xf0(%rbp,%rcx,4), %cl
sarl %cl, %eax
jmp 0x52bd
movq -0x40(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x48(%rbp), %rcx
movb -0xf0(%rbp,%rcx,4), %cl
shrl %cl, %eax
jmp 0x52bd
xorl %eax, %eax
movl -0x2c(%rbp), %ecx
movq -0x40(%rbp), %rdx
cmpl %ecx, -0xf0(%rbp,%rdx,4)
setl %al
jmp 0x52bd
xorl %eax, %eax
movl -0x2c(%rbp), %ecx
movq -0x40(%rbp), %rdx
cmpl %ecx, -0xf0(%rbp,%rdx,4)
setb %al
movq -0x38(%rbp), %rcx
movl %eax, -0xf0(%rbp,%rcx,4)
leal 0xffff(%r12), %r15d
testl %r12d, %r12d
cmovnsl %r12d, %r15d
movl $0x0, -0xf0(%rbp)
testb $0x1, -0x54(%rbp)
je 0x5322
xorl %ebx, %ebx
movl -0xf0(%rbp,%rbx,4), %ecx
movl -0x270(%rbp,%rbx,4), %edx
cmpl %edx, %ecx
je 0x530b
leaq 0x66a7(%rip), %rdi      # 0xb9a9
movl %ebx, %esi
xorl %eax, %eax
callq 0x2040
movl -0xf0(%rbp,%rbx,4), %eax
movl %eax, -0x270(%rbp,%rbx,4)
incq %rbx
cmpq $0x20, %rbx
jne 0x52e9
andl $0xffff0000, %r15d      # imm = 0xFFFF0000
subl %r15d, %r12d
movq 0x8c7d(%rip), %rax      # 0xdfb0
movq (%rax), %rdi
callq 0x21f0
movl %r12d, %ebx
testb $0x1, -0xf8(%rbp)
leaq -0x128(%rbp), %r12
leaq -0x1f0(%rbp), %r15
je 0x4997
jmp 0x53b1
leaq 0x6795(%rip), %rdi      # 0xbaf7
callq 0x22e0
movq -0x108(%rbp), %rsi
testq %rsi, %rsi
je 0x5381
leaq 0x661e(%rip), %rdi      # 0xb998
xorl %eax, %eax
callq 0x2040
leaq 0x65b5(%rip), %rdi      # 0xb93d
movl -0x58(%rbp), %esi
movl %ebx, %edx
movl -0x64(%rbp), %ecx
xorl %eax, %eax
callq 0x2040
leaq -0xf0(%rbp), %rdi
callq 0x2814
movb $0x1, %al
movq %rax, -0xf8(%rbp)
jmp 0x52c8
addq $0x248, %rsp            # imm = 0x248
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x6753(%rip), %rdi      # 0xbb1d
callq 0x22e0
xorl %edi, %edi
callq 0x2210
movq %rax, %rbx
movq -0x168(%rbp), %rdi
leaq -0x158(%rbp), %rax
cmpq %rax, %rdi
je 0x53f6
callq 0x2180
jmp 0x53f6
movq %rax, %rbx
movq -0x138(%rbp), %rdi
cmpq %r12, %rdi
je 0x5407
callq 0x2180
movq %rbx, %rdi
callq 0x2370