// File: /workspace/github_cpp_makefile_star2_O3/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 $0x238, %rsp            # imm = 0x238
movq %rsi, -0x58(%rbp)
movq %rdi, %r14
xorps %xmm0, %xmm0
leaq -0x100(%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, -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)
movaps %xmm0, -0x1f0(%rbp)
xorb $0x1, %r8b
movl %r8d, -0x5c(%rbp)
leaq -0x118(%rbp), %r13
leaq 0x6f3f(%rip), %r15      # 0xb8c2
xorl %ebx, %ebx
movl $0x0, -0x60(%rbp)
movl $0x0, -0x68(%rbp)
movl %ebx, %eax
shrl $0x2, %eax
imulq $0x98, %rax, %rax
movq -0x58(%rbp), %rcx
movl (%rcx,%rax), %edx
movq %rdx, -0x130(%rbp)
movl 0x58(%rcx,%rax), %edx
movl %edx, -0x64(%rbp)
movslq 0x28(%rcx,%rax), %rsi
movslq 0x54(%rcx,%rax), %rdx
movq %rdx, -0x48(%rbp)
movslq 0x80(%rcx,%rax), %rdx
movq %rdx, -0x50(%rbp)
movl 0x84(%rcx,%rax), %edi
movq 0x88(%rcx,%rax), %rdx
movq %rdx, -0x108(%rbp)
movl 0x90(%rcx,%rax), %edx
movl %edx, -0x6c(%rbp)
movb 0x94(%rcx,%rax), %al
incl -0x60(%rbp)
testb $0x1, -0x5c(%rbp)
movq %rsi, -0x40(%rbp)
movl %edi, -0x2c(%rbp)
jne 0x4a0d
testb $0x1, %al
je 0x4ef4
xorl %ecx, %ecx
movl -0x68(%rbp), %edx
testl %edx, %edx
setg %cl
subl %ecx, %edx
movl %edx, -0x68(%rbp)
je 0x4a26
testb $0x1, %al
je 0x4ef4
movl $0xa, %edi
callq 0x2270
movq -0x108(%rbp), %rsi
testq %rsi, %rsi
je 0x4a4a
leaq 0x6de0(%rip), %rdi      # 0xb823
xorl %eax, %eax
callq 0x2040
movb $0x1, %al
movl %eax, -0x5c(%rbp)
movq %rbx, -0x138(%rbp)
leaq 0x6dd0(%rip), %rdi      # 0xb82d
movl -0x60(%rbp), %esi
movl %ebx, %edx
movl -0x6c(%rbp), %ecx
xorl %eax, %eax
callq 0x2040
movq %r13, -0x128(%rbp)
movq $0x0, -0x120(%rbp)
movb $0x0, -0x118(%rbp)
movq 0x9524(%rip), %rax      # 0xdfb0
movq (%rax), %rdi
callq 0x21f0
leaq 0x6ede(%rip), %rdi      # 0xb979
callq 0x2220
testq %rax, %rax
je 0x4acc
movq %rax, %rbx
xorl %r12d, %r12d
leaq 0x92ce(%rip), %rax      # 0xdd80
movq (%r12,%rax), %rsi
movq %rbx, %rdi
callq 0x21d0
testl %eax, %eax
je 0x4ae8
addq $0x8, %r12
cmpq $0x18, %r12
jne 0x4aab
leaq 0x6d7d(%rip), %rdi      # 0xb850
leaq -0x128(%rbp), %rsi
callq 0x580e
leaq -0x1e0(%rbp), %r12
jmp 0x4b44
leaq 0x6b9a(%rip), %rdi      # 0xb689
leaq 0x6d5a(%rip), %rsi      # 0xb850
xorl %eax, %eax
callq 0x2040
movq 0x94ac(%rip), %rax      # 0xdfb0
movq (%rax), %rdi
callq 0x21f0
movq 0x94c5(%rip), %rcx      # 0xdfd8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x2190
leaq -0x1e0(%rbp), %r12
movsbl %al, %edx
movq 0x94a0(%rip), %rdi      # 0xdfd8
leaq -0x128(%rbp), %rsi
callq 0x2390
movq -0x128(%rbp), %rbx
movl $0x80, %edx
movq %r12, %rdi
movq %rbx, %rsi
callq 0x2150
movq 0x9fc6(%rip), %rsi      # 0xeb28
movq 0x9fc7(%rip), %rdi      # 0xeb30
movq %rsi, %rax
cmpq %rdi, %rsi
je 0x4b8f
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 0x7130
leaq -0x158(%rbp), %rdi
movq %rbx, %rsi
leaq -0x6d(%rbp), %rdx
callq 0x20d0
leaq 0x9f68(%rip), %rdi      # 0xeb28
leaq -0x158(%rbp), %rsi
callq 0x71a6
movq -0x158(%rbp), %rdi
leaq -0x148(%rbp), %rax
cmpq %rax, %rdi
je 0x4be4
callq 0x2180
cmpb $0x0, -0x1e0(%rbp)
je 0x4c57
xorl %ebx, %ebx
cmpb $0xa, -0x1e0(%rbp,%rbx)
jne 0x4c01
movb $0x0, -0x1e0(%rbp,%rbx)
incq %rbx
movq %r12, %rdi
callq 0x20f0
cmpq %rbx, %rax
ja 0x4bef
movzbl -0x1e0(%rbp), %ecx
xorl %ebx, %ebx
cmpl $0x63, %ecx
je 0x4c5b
cmpl $0x71, %ecx
je 0x53a2
testq %rax, %rax
je 0x4c57
cmpl $0x62, %ecx
je 0x4c87
cmpl $0x73, %ecx
jne 0x4d1e
xorl %ebx, %ebx
leaq -0x1df(%rbp), %rdi
movl $0x10, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x319b
movl %eax, -0x68(%rbp)
jmp 0x4c62
xorl %ebx, %ebx
jmp 0x4c62
movl $0x0, -0x5c(%rbp)
movq -0x128(%rbp), %rdi
cmpq %r13, %rdi
je 0x4c73
callq 0x2180
testb %bl, %bl
movq -0x138(%rbp), %rbx
jne 0x4a56
jmp 0x4ef4
leaq -0x1df(%rbp), %rdi
movl $0x10, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x319b
cmpb $0x0, -0x1df(%rbp)
leaq 0x6ba9(%rip), %r12      # 0xb853
movl $0x94, %ebx
je 0x4ccd
movq -0x58(%rbp), %rcx
cmpl %eax, -0x4(%rcx,%rbx)
jae 0x4d00
addq $0x98, %rbx
cmpq $0x130094, %rbx         # imm = 0x130094
jne 0x4cb5
jmp 0x4d18
movq -0x58(%rbp), %rax
cmpb $0x1, (%rax,%rbx)
jne 0x4cee
movl -0x4(%rax,%rbx), %esi
movq -0xc(%rax,%rbx), %rdx
movq %r12, %rdi
xorl %eax, %eax
callq 0x2040
movq -0x58(%rbp), %rax
addq $0x98, %rbx
cmpq $0x130094, %rbx         # imm = 0x130094
jne 0x4cd1
jmp 0x4d18
leaq 0x6b62(%rip), %rdi      # 0xb869
movl %eax, %esi
xorl %eax, %eax
callq 0x2040
movq -0x58(%rbp), %rax
movb $0x1, (%rax,%rbx)
movb -0x1e0(%rbp), %cl
cmpb $0x42, %cl
jne 0x4d77
leaq -0x1df(%rbp), %rdi
movl $0x10, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x319b
movq -0x58(%rbp), %rcx
movl $0x94, %ebx
cmpl %eax, -0x4(%rcx,%rbx)
jne 0x4d4d
cmpb $0x1, (%rcx,%rbx)
je 0x4d5f
addq $0x98, %rbx
cmpq $0x130094, %rbx         # imm = 0x130094
jne 0x4d41
jmp 0x4d77
leaq 0x6b21(%rip), %rdi      # 0xb887
movl %eax, %esi
xorl %eax, %eax
callq 0x2040
movq -0x58(%rbp), %rax
movb $0x0, (%rax,%rbx)
movb -0x1e0(%rbp), %al
cmpb $0x72, %al
jne 0x4dc2
leaq -0x1df(%rbp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2d50
testl %eax, %eax
js 0x4db0
movl %eax, %ecx
movl -0x100(%rbp,%rcx,4), %edx
leaq 0x6b04(%rip), %rdi      # 0xb8a9
movl %eax, %esi
xorl %eax, %eax
callq 0x2040
jmp 0x4dbc
leaq -0x100(%rbp), %rdi
callq 0x2814
movb -0x1e0(%rbp), %al
cmpb $0x6d, %al
jne 0x4e7b
leaq -0x1df(%rbp), %rdi
movl $0x1f, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x319b
movq %rax, -0x38(%rbp)
leaq -0x1e0(%rbp), %rdi
leaq 0x68ab(%rip), %rbx      # 0xb69c
movq %rbx, %rsi
callq 0x2320
xorl %edi, %edi
movq %rbx, %rsi
callq 0x2320
testq %rax, %rax
je 0x4e22
movq %rax, %rdi
movl $0x10, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x319b
movl %eax, -0x74(%rbp)
testl %eax, %eax
jg 0x4e29
jmp 0x4e7b
movl $0x1, -0x74(%rbp)
movl -0x38(%rbp), %r13d
xorl %r12d, %r12d
movq -0x38(%rbp), %rax
leal (%rax,%r12,4), %esi
leaq 0x6a7a(%rip), %rdi      # 0xb8b9
xorl %eax, %eax
callq 0x2040
xorl %ebx, %ebx
leal (%rbx,%r13), %eax
movzbl (%r14,%rax), %esi
movq %r15, %rdi
xorl %eax, %eax
callq 0x2040
incq %rbx
cmpq $0x4, %rbx
jne 0x4e48
movl $0xa, %edi
callq 0x2270
incl %r12d
addq $0x4, %r13
cmpl -0x74(%rbp), %r12d
jne 0x4e30
movb $0x1, %bl
cmpb $0x6c, -0x1e0(%rbp)
jne 0x4ee8
leaq 0x6b89(%rip), %rdi      # 0xba16
callq 0x22e0
leaq 0x6b9b(%rip), %rdi      # 0xba34
callq 0x22e0
movl $0x90, %r12d
leaq -0x118(%rbp), %r13
movq -0x58(%rbp), %rax
movl (%rax,%r12), %esi
testl %esi, %esi
js 0x4ed3
movq -0x8(%rax,%r12), %rdx
testq %rdx, %rdx
je 0x4ed3
leaq 0x6a00(%rip), %rdi      # 0xb8c8
xorl %eax, %eax
callq 0x2040
movq -0x58(%rbp), %rax
addq $0x98, %r12
cmpq $0x130090, %r12         # imm = 0x130090
jne 0x4eaf
jmp 0x4c62
leaq -0x118(%rbp), %r13
jmp 0x4c62
leal 0x4(%rbx), %r12d
movq -0x130(%rbp), %r8
leal -0x1(%r8), %eax
cmpl $0x25, %eax
ja 0x533e
leaq 0x31d1(%rip), %rcx      # 0x80e4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl -0x2c(%rbp), %esi
movq -0x48(%rbp), %rax
addl -0x100(%rbp,%rax,4), %esi
movq %r14, %rdi
movl %r8d, %edx
callq 0x3394
jmp 0x52a3
movl -0x2c(%rbp), %esi
movq -0x48(%rbp), %rax
addl -0x100(%rbp,%rax,4), %esi
movq -0x40(%rbp), %rax
movl -0x100(%rbp,%rax,4), %edx
movq %r14, %rdi
movl %r8d, %ecx
callq 0x32a6
jmp 0x52ae
movq -0x50(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
movq -0x48(%rbp), %rcx
addl -0x100(%rbp,%rcx,4), %eax
jmp 0x52a3
leaq 0x6acf(%rip), %rdi      # 0xba54
callq 0x22e0
leaq 0x6ad1(%rip), %rdi      # 0xba62
callq 0x22e0
leaq 0x6934(%rip), %rdi      # 0xb8d1
movl -0x60(%rbp), %esi
movl %ebx, %edx
movl -0x6c(%rbp), %ecx
xorl %eax, %eax
callq 0x2040
leaq -0x100(%rbp), %rdi
callq 0x2814
movl 0x9b92(%rip), %esi      # 0xeb50
movl 0x9b88(%rip), %edx      # 0xeb4c
movl 0x9b7e(%rip), %ecx      # 0xeb48
movl 0x9b73(%rip), %r8d      # 0xeb44
leaq 0x6919(%rip), %rdi      # 0xb8f1
xorl %eax, %eax
callq 0x2040
movl 0x9b5b(%rip), %esi      # 0xeb40
leaq 0x6929(%rip), %rdi      # 0xb915
xorl %eax, %eax
callq 0x2040
jmp 0x5386
movq -0x50(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
movq -0x48(%rbp), %rcx
xorl -0x100(%rbp,%rcx,4), %eax
jmp 0x52a3
movl -0x2c(%rbp), %ecx
movq -0x48(%rbp), %rax
xorl -0x100(%rbp,%rax,4), %ecx
jmp 0x523a
movq -0x48(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
movl -0x2c(%rbp), %ecx
jmp 0x5191
movq -0x48(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
xorl %ecx, %ecx
movq -0x50(%rbp), %rdx
cmpl -0x100(%rbp,%rdx,4), %eax
setl %cl
jmp 0x523a
movl -0x64(%rbp), %ecx
shll $0xc, %ecx
jmp 0x523a
movq -0x48(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
movq -0x50(%rbp), %rcx
subl -0x100(%rbp,%rcx,4), %eax
jmp 0x52a3
movq -0x48(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
movl -0x2c(%rbp), %ecx
jmp 0x5277
movq -0x40(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
movq -0x48(%rbp), %rcx
cmpl -0x100(%rbp,%rcx,4), %eax
movl -0x2c(%rbp), %eax
cmovel %r12d, %eax
jmp 0x51f5
movl -0x2c(%rbp), %ecx
movq -0x48(%rbp), %rax
andl -0x100(%rbp,%rax,4), %ecx
jmp 0x523a
movq -0x40(%rbp), %rax
movl %r12d, -0x100(%rbp,%rax,4)
movl $0x0, -0x38(%rbp)
movl -0x64(%rbp), %eax
jmp 0x51fc
movq -0x40(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
movq -0x48(%rbp), %rcx
cmpl -0x100(%rbp,%rcx,4), %eax
cmovll -0x2c(%rbp), %r12d
jmp 0x52ae
movl -0x2c(%rbp), %ecx
movq -0x48(%rbp), %rax
addl -0x100(%rbp,%rax,4), %ecx
jmp 0x523a
movq -0x50(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
movq -0x48(%rbp), %rcx
andl -0x100(%rbp,%rcx,4), %eax
jmp 0x52a3
movq -0x40(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
movq -0x48(%rbp), %rcx
cmpl -0x100(%rbp,%rcx,4), %eax
movl -0x2c(%rbp), %eax
cmovll %r12d, %eax
jmp 0x51f5
movl -0x64(%rbp), %ecx
shll $0xc, %ecx
addl %ebx, %ecx
jmp 0x523a
movq -0x40(%rbp), %rax
movl %r12d, -0x100(%rbp,%rax,4)
movl -0x2c(%rbp), %eax
movq -0x48(%rbp), %rcx
addl -0x100(%rbp,%rcx,4), %eax
jmp 0x51f5
movq -0x48(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
movq -0x50(%rbp), %rcx
movb -0x100(%rbp,%rcx,4), %cl
shll %cl, %eax
jmp 0x52a3
movq -0x40(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
movq -0x48(%rbp), %rcx
cmpl -0x100(%rbp,%rcx,4), %eax
cmovel -0x2c(%rbp), %r12d
jmp 0x52ae
movq -0x40(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
movq -0x48(%rbp), %rcx
cmpl -0x100(%rbp,%rcx,4), %eax
cmovbl -0x2c(%rbp), %r12d
jmp 0x52ae
movq -0x40(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
movq -0x48(%rbp), %rcx
cmpl -0x100(%rbp,%rcx,4), %eax
movl -0x2c(%rbp), %eax
cmovbl %r12d, %eax
movl $0x0, -0x38(%rbp)
movl %eax, %r12d
jmp 0x52b5
movq -0x48(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
movl -0x2c(%rbp), %ecx
jmp 0x525d
movq -0x50(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
movq -0x48(%rbp), %rcx
orl -0x100(%rbp,%rcx,4), %eax
jmp 0x52a3
movl -0x2c(%rbp), %ecx
movq -0x48(%rbp), %rax
orl -0x100(%rbp,%rax,4), %ecx
movq -0x40(%rbp), %rax
movl %ecx, -0x100(%rbp,%rax,4)
jmp 0x52ae
movq -0x48(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
movq -0x50(%rbp), %rcx
movb -0x100(%rbp,%rcx,4), %cl
sarl %cl, %eax
jmp 0x52a3
movq -0x48(%rbp), %rax
movl -0x100(%rbp,%rax,4), %eax
movq -0x50(%rbp), %rcx
movb -0x100(%rbp,%rcx,4), %cl
shrl %cl, %eax
jmp 0x52a3
xorl %eax, %eax
movl -0x2c(%rbp), %ecx
movq -0x48(%rbp), %rdx
cmpl %ecx, -0x100(%rbp,%rdx,4)
setl %al
jmp 0x52a3
xorl %eax, %eax
movl -0x2c(%rbp), %ecx
movq -0x48(%rbp), %rdx
cmpl %ecx, -0x100(%rbp,%rdx,4)
setb %al
movq -0x40(%rbp), %rcx
movl %eax, -0x100(%rbp,%rcx,4)
movl $0x0, -0x38(%rbp)
leal 0xffff(%r12), %r13d
testl %r12d, %r12d
cmovnsl %r12d, %r13d
movl $0x0, -0x100(%rbp)
testb $0x1, -0x5c(%rbp)
je 0x530f
xorl %ebx, %ebx
movl -0x100(%rbp,%rbx,4), %ecx
movl -0x260(%rbp,%rbx,4), %edx
cmpl %edx, %ecx
je 0x52ff
leaq 0x664e(%rip), %rdi      # 0xb93d
movl %ebx, %esi
xorl %eax, %eax
callq 0x2040
movl -0x100(%rbp,%rbx,4), %ecx
movl %ecx, -0x260(%rbp,%rbx,4)
incq %rbx
cmpq $0x20, %rbx
jne 0x52d6
andl $0xffff0000, %r13d      # imm = 0xFFFF0000
subl %r13d, %r12d
movq 0x8c90(%rip), %rax      # 0xdfb0
movq (%rax), %rdi
callq 0x21f0
movl %r12d, %ebx
cmpb $0x0, -0x38(%rbp)
leaq -0x118(%rbp), %r13
je 0x4993
jmp 0x5390
leaq 0x6746(%rip), %rdi      # 0xba8b
callq 0x22e0
movq -0x108(%rbp), %rsi
testq %rsi, %rsi
je 0x5364
leaq 0x65cf(%rip), %rdi      # 0xb92c
xorl %eax, %eax
callq 0x2040
leaq 0x6566(%rip), %rdi      # 0xb8d1
movl -0x60(%rbp), %esi
movl %ebx, %edx
movl -0x6c(%rbp), %ecx
xorl %eax, %eax
callq 0x2040
leaq -0x100(%rbp), %rdi
callq 0x2814
movb $0x1, %al
movl %eax, -0x38(%rbp)
jmp 0x52b5
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x6708(%rip), %rdi      # 0xbab1
callq 0x22e0
xorl %edi, %edi
callq 0x2210
movq %rax, %rbx
movq -0x158(%rbp), %rdi
leaq -0x148(%rbp), %rax
cmpq %rax, %rdi
je 0x53d5
callq 0x2180
jmp 0x53d5
movq %rax, %rbx
movq -0x128(%rbp), %rdi
cmpq %r13, %rdi
je 0x53e6
callq 0x2180
movq %rbx, %rdi
callq 0x2370