// File: /workspace/github_cpp_makefile_star2_O2/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 $0x208, %rsp            # imm = 0x208
movl %r8d, -0x44(%rbp)
movq %rdi, %r14
xorl %eax, %eax
cmpq $0x20, %rax
je 0x45e9
andl $0x0, -0xf0(%rbp,%rax,4)
andl $0x0, -0x230(%rbp,%rax,4)
incq %rax
jmp 0x45ce
movq %rsi, -0x100(%rbp)
movl -0x44(%rbp), %eax
xorb $0x1, %al
movl %eax, -0x44(%rbp)
leaq -0x128(%rbp), %rbx
xorl %r12d, %r12d
movl $0x0, -0x68(%rbp)
movl $0x0, -0x54(%rbp)
movq $0x0, -0x60(%rbp)
testb $0x1, %r12b
jne 0x4ebd
movq -0x60(%rbp), %rax
shrl $0x2, %eax
imulq $0x98, %rax, %rax
movq -0x100(%rbp), %r12
movl (%r12,%rax), %edx
movl 0x58(%r12,%rax), %ecx
movl %ecx, -0x64(%rbp)
movslq 0x28(%r12,%rax), %rcx
movq %rcx, -0x38(%rbp)
movslq 0x54(%r12,%rax), %rcx
movq %rcx, -0x40(%rbp)
movslq 0x80(%r12,%rax), %rcx
movq %rcx, -0x50(%rbp)
movl 0x84(%r12,%rax), %ecx
movl %ecx, -0x2c(%rbp)
movq 0x88(%r12,%rax), %rcx
movq %rcx, -0xf8(%rbp)
movl 0x90(%r12,%rax), %ecx
movl %ecx, -0x6c(%rbp)
movb 0x94(%r12,%rax), %al
incl -0x54(%rbp)
testb $0x1, -0x44(%rbp)
movq %rdx, -0x130(%rbp)
jne 0x46a6
testb $0x1, %al
je 0x4a4e
xorl %ecx, %ecx
movl -0x68(%rbp), %edx
testl %edx, %edx
setg %cl
subl %ecx, %edx
movl %edx, -0x68(%rbp)
je 0x46bf
testb $0x1, %al
je 0x4a4e
pushq $0xa
popq %rdi
callq 0x2290
movq -0xf8(%rbp), %rsi
testq %rsi, %rsi
je 0x46e1
leaq 0x61b5(%rip), %rdi      # 0xa88f
xorl %eax, %eax
callq 0x2040
movb $0x1, %al
movl %eax, -0x44(%rbp)
leaq 0x61ac(%rip), %rdi      # 0xa899
movl -0x54(%rbp), %esi
movq -0x60(%rbp), %rdx
movl -0x6c(%rbp), %ecx
xorl %eax, %eax
callq 0x2040
leaq -0x118(%rbp), %rax
movq %rax, -0x128(%rbp)
andq $0x0, -0x120(%rbp)
movb $0x0, -0x118(%rbp)
movq 0x888e(%rip), %rax      # 0xcfb0
movq (%rax), %rdi
callq 0x21e0
leaq 0x618b(%rip), %rdi      # 0xa8bc
movq %rbx, %rsi
callq 0x52d1
movq -0x128(%rbp), %rbx
movl $0x80, %edx
leaq -0x1b0(%rbp), %rdi
movq %rbx, %rsi
callq 0x2150
movq %rbx, %rdi
callq 0x532c
xorl %ebx, %ebx
leaq -0x1b0(%rbp), %rdi
callq 0x20f0
cmpq %rbx, %rax
jbe 0x4786
cmpb $0xa, -0x1b0(%rbp,%rbx)
jne 0x4781
movb $0x0, -0x1b0(%rbp,%rbx)
incq %rbx
jmp 0x475e
movzbl -0x1b0(%rbp), %ecx
cmpl $0x63, %ecx
je 0x47cc
cmpl $0x71, %ecx
je 0x4ecf
testq %rax, %rax
je 0x47db
cmpl $0x62, %ecx
je 0x47e3
cmpl $0x73, %ecx
jne 0x483a
xorl %r15d, %r15d
leaq -0x1af(%rbp), %rdi
pushq $0x10
popq %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x2fc6
movl %eax, -0x68(%rbp)
jmp 0x4a36
xorl %r15d, %r15d
movl $0x0, -0x44(%rbp)
jmp 0x4a36
xorl %r15d, %r15d
jmp 0x4a36
leaq -0x1af(%rbp), %rdi
pushq $0x10
popq %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x2fc6
cmpb $0x0, -0x1af(%rbp)
je 0x487b
pushq $-0x4
popq %rcx
leaq 0x98(%rcx), %rbx
cmpq $0x130094, %rbx         # imm = 0x130094
je 0x4834
cmpl %eax, 0x94(%r12,%rcx)
movq %rbx, %rcx
jb 0x4802
leaq 0x60af(%rip), %rdi      # 0xa8d5
movl %eax, %esi
xorl %eax, %eax
callq 0x2040
movb $0x1, (%r12,%rbx)
movb -0x1b0(%rbp), %cl
cmpb $0x42, %cl
jne 0x48c6
leaq -0x1af(%rbp), %rdi
pushq $0x10
popq %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x2fc6
movl $0x94, %ebx
cmpq $0x130094, %rbx         # imm = 0x130094
je 0x48c6
cmpl %eax, -0x4(%r12,%rbx)
jne 0x4872
cmpb $0x1, (%r12,%rbx)
je 0x48b1
addq $0x98, %rbx
jmp 0x485b
movl $0x94, %ebx
cmpq $0x130094, %rbx         # imm = 0x130094
je 0x4834
cmpb $0x1, (%r12,%rbx)
jne 0x48a8
movl -0x4(%r12,%rbx), %esi
movq -0xc(%r12,%rbx), %rdx
leaq 0x601e(%rip), %rdi      # 0xa8bf
xorl %eax, %eax
callq 0x2040
addq $0x98, %rbx
jmp 0x4880
leaq 0x603b(%rip), %rdi      # 0xa8f3
movl %eax, %esi
xorl %eax, %eax
callq 0x2040
movb $0x0, (%r12,%rbx)
movb -0x1b0(%rbp), %al
cmpb $0x72, %al
jne 0x4911
leaq -0x1af(%rbp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2c37
testl %eax, %eax
js 0x48ff
movl %eax, %ecx
movl -0xf0(%rbp,%rcx,4), %edx
leaq 0x6021(%rip), %rdi      # 0xa915
movl %eax, %esi
xorl %eax, %eax
callq 0x2040
jmp 0x490b
leaq -0xf0(%rbp), %rdi
callq 0x280e
movb -0x1b0(%rbp), %al
cmpb $0x6d, %al
jne 0x49df
leaq -0x1af(%rbp), %rdi
pushq $0x1f
popq %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x2fc6
movq %rax, -0x108(%rbp)
leaq -0x1b0(%rbp), %rdi
leaq 0x5dc1(%rip), %rbx      # 0xa702
movq %rbx, %rsi
callq 0x2330
xorl %edi, %edi
movq %rbx, %rsi
callq 0x2330
pushq $0x1
popq %r13
testq %rax, %rax
je 0x496e
movq %rax, %rdi
pushq $0x10
popq %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x2fc6
movl %eax, %r13d
xorl %r15d, %r15d
testl %r13d, %r13d
cmovlel %r15d, %r13d
movl -0x108(%rbp), %r12d
cmpl %r13d, %r15d
je 0x49d2
movq -0x108(%rbp), %rax
leal (%rax,%r15,4), %esi
leaq 0x5f8f(%rip), %rdi      # 0xa925
xorl %eax, %eax
callq 0x2040
xorl %ebx, %ebx
cmpq $0x4, %rbx
je 0x49c1
leal (%r12,%rbx), %eax
movzbl (%r14,%rax), %esi
leaq 0x5f79(%rip), %rdi      # 0xa92e
xorl %eax, %eax
callq 0x2040
incq %rbx
jmp 0x499f
pushq $0xa
popq %rdi
callq 0x2290
incl %r15d
addq $0x4, %r12
jmp 0x497f
movb -0x1b0(%rbp), %al
movq -0x100(%rbp), %r12
cmpb $0x6c, %al
jne 0x4a33
leaq 0x606e(%rip), %rdi      # 0xaa58
callq 0x2300
leaq 0x6080(%rip), %rdi      # 0xaa76
callq 0x2300
movl $0x90, %r15d
cmpq $0x130090, %r15         # imm = 0x130090
je 0x4a33
movl (%r12,%r15), %esi
testl %esi, %esi
js 0x4a2a
movq -0x8(%r12,%r15), %rdx
testq %rdx, %rdx
je 0x4a2a
leaq 0x5f11(%rip), %rdi      # 0xa934
xorl %eax, %eax
callq 0x2040
addq $0x98, %r15
jmp 0x4a01
movb $0x1, %r15b
leaq -0x128(%rbp), %rbx
movq %rbx, %rdi
callq 0x2100
testb %r15b, %r15b
jne 0x46e6
movq -0x60(%rbp), %rax
leal 0x4(%rax), %ebx
movq -0x130(%rbp), %r8
leal -0x1(%r8), %eax
cmpl $0x25, %eax
ja 0x4e6b
leaq 0x2674(%rip), %rcx      # 0x70e4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl -0x2c(%rbp), %esi
movq -0x40(%rbp), %rax
addl -0xf0(%rbp,%rax,4), %esi
movq %r14, %rdi
movl %r8d, %edx
callq 0x31a6
jmp 0x4dea
movl -0x2c(%rbp), %esi
movq -0x40(%rbp), %rax
addl -0xf0(%rbp,%rax,4), %esi
movq -0x38(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %edx
movq %r14, %rdi
movl %r8d, %ecx
callq 0x30c2
jmp 0x4df5
movq -0x50(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
addl -0xf0(%rbp,%rcx,4), %eax
jmp 0x4dea
leaq 0x5fb4(%rip), %rdi      # 0xaa96
callq 0x2300
leaq 0x5fb6(%rip), %rdi      # 0xaaa4
callq 0x2300
leaq 0x5e43(%rip), %rdi      # 0xa93d
movl -0x54(%rbp), %esi
movq -0x60(%rbp), %rdx
movl -0x6c(%rbp), %ecx
xorl %eax, %eax
callq 0x2040
leaq -0xf0(%rbp), %rdi
callq 0x280e
movl 0x9043(%rip), %esi      # 0xdb60
movl 0x9039(%rip), %edx      # 0xdb5c
movl 0x902f(%rip), %ecx      # 0xdb58
movl 0x9024(%rip), %r8d      # 0xdb54
leaq 0x5e26(%rip), %rdi      # 0xa95d
xorl %eax, %eax
callq 0x2040
movl 0x900c(%rip), %esi      # 0xdb50
leaq 0x5e36(%rip), %rdi      # 0xa981
xorl %eax, %eax
callq 0x2040
jmp 0x4eb5
movq -0x50(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
xorl -0xf0(%rbp,%rcx,4), %eax
jmp 0x4dea
movl -0x2c(%rbp), %ecx
movq -0x40(%rbp), %rax
xorl -0xf0(%rbp,%rax,4), %ecx
jmp 0x4d81
movq -0x40(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movl -0x2c(%rbp), %ecx
jmp 0x4ce7
movq -0x40(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
xorl %ecx, %ecx
movq -0x50(%rbp), %rdx
cmpl -0xf0(%rbp,%rdx,4), %eax
setl %cl
jmp 0x4d81
movl -0x64(%rbp), %ecx
shll $0xc, %ecx
jmp 0x4d81
movq -0x40(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x50(%rbp), %rcx
subl -0xf0(%rbp,%rcx,4), %eax
jmp 0x4dea
movq -0x40(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movl -0x2c(%rbp), %ecx
jmp 0x4dbe
movq -0x38(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
cmpl -0xf0(%rbp,%rcx,4), %eax
cmovnel -0x2c(%rbp), %ebx
jmp 0x4df5
movl -0x2c(%rbp), %ecx
movq -0x40(%rbp), %rax
andl -0xf0(%rbp,%rax,4), %ecx
jmp 0x4d81
movq -0x38(%rbp), %rax
movl %ebx, -0xf0(%rbp,%rax,4)
xorl %r12d, %r12d
movl -0x64(%rbp), %ebx
jmp 0x4df8
movq -0x38(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
cmpl -0xf0(%rbp,%rcx,4), %eax
cmovll -0x2c(%rbp), %ebx
jmp 0x4df5
movl -0x2c(%rbp), %ecx
movq -0x40(%rbp), %rax
addl -0xf0(%rbp,%rax,4), %ecx
jmp 0x4d81
movq -0x50(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
andl -0xf0(%rbp,%rcx,4), %eax
jmp 0x4dea
movq -0x38(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
cmpl -0xf0(%rbp,%rcx,4), %eax
cmovgel -0x2c(%rbp), %ebx
jmp 0x4df5
movl -0x64(%rbp), %ecx
shll $0xc, %ecx
addl -0x60(%rbp), %ecx
jmp 0x4d81
movq -0x38(%rbp), %rax
movl %ebx, -0xf0(%rbp,%rax,4)
movl -0x2c(%rbp), %ebx
movq -0x40(%rbp), %rcx
addl -0xf0(%rbp,%rcx,4), %ebx
jmp 0x4df5
movq -0x40(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x50(%rbp), %rcx
movb -0xf0(%rbp,%rcx,4), %cl
shll %cl, %eax
jmp 0x4dea
movq -0x38(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
cmpl -0xf0(%rbp,%rcx,4), %eax
cmovel -0x2c(%rbp), %ebx
jmp 0x4df5
movq -0x38(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
cmpl -0xf0(%rbp,%rcx,4), %eax
cmovbl -0x2c(%rbp), %ebx
jmp 0x4df5
movq -0x38(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
cmpl -0xf0(%rbp,%rcx,4), %eax
cmovael -0x2c(%rbp), %ebx
jmp 0x4df5
movq -0x40(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movl -0x2c(%rbp), %ecx
jmp 0x4da4
movq -0x50(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x40(%rbp), %rcx
orl -0xf0(%rbp,%rcx,4), %eax
jmp 0x4dea
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 0x4df5
movq -0x40(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x50(%rbp), %rcx
movb -0xf0(%rbp,%rcx,4), %cl
sarl %cl, %eax
jmp 0x4dea
movq -0x40(%rbp), %rax
movl -0xf0(%rbp,%rax,4), %eax
movq -0x50(%rbp), %rcx
movb -0xf0(%rbp,%rcx,4), %cl
shrl %cl, %eax
jmp 0x4dea
xorl %eax, %eax
movl -0x2c(%rbp), %ecx
movq -0x40(%rbp), %rdx
cmpl %ecx, -0xf0(%rbp,%rdx,4)
setl %al
jmp 0x4dea
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)
xorl %r12d, %r12d
movl %ebx, %eax
cltd
movl $0x10000, %ecx          # imm = 0x10000
idivl %ecx
movq %rdx, -0x60(%rbp)
andl $0x0, -0xf0(%rbp)
testb $0x1, -0x44(%rbp)
je 0x4e50
xorl %ebx, %ebx
cmpq $0x20, %rbx
je 0x4e50
movl -0xf0(%rbp,%rbx,4), %ecx
movl -0x230(%rbp,%rbx,4), %edx
cmpl %edx, %ecx
je 0x4e44
leaq 0x5b75(%rip), %rdi      # 0xa9a9
movl %ebx, %esi
xorl %eax, %eax
callq 0x2040
movl -0xf0(%rbp,%rbx,4), %ecx
movl %ecx, -0x230(%rbp,%rbx,4)
incq %rbx
jmp 0x4e15
movq 0x8159(%rip), %rax      # 0xcfb0
movq (%rax), %rdi
callq 0x21e0
leaq -0x128(%rbp), %rbx
jmp 0x4618
leaq 0x5c5b(%rip), %rdi      # 0xaacd
callq 0x2300
movq -0xf8(%rbp), %rsi
testq %rsi, %rsi
je 0x4e91
leaq 0x5b0e(%rip), %rdi      # 0xa998
xorl %eax, %eax
callq 0x2040
leaq 0x5aa5(%rip), %rdi      # 0xa93d
movl -0x54(%rbp), %esi
movq -0x60(%rbp), %rdx
movl -0x6c(%rbp), %ecx
xorl %eax, %eax
callq 0x2040
leaq -0xf0(%rbp), %rdi
callq 0x280e
movb $0x1, %r12b
jmp 0x4df8
addq $0x208, %rsp            # imm = 0x208
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x5c1d(%rip), %rdi      # 0xaaf3
callq 0x2300
xorl %edi, %edi
callq 0x2200
movq %rax, %rbx
leaq -0x128(%rbp), %rdi
callq 0x2100
movq %rbx, %rdi
callq 0x2380