// File: /workspace/github_c_makefile_star2_O0/minkcv[P]vm/machine/cpu.c
// Function: exec
void exec(CPU* cpu, Instruction* instr, uint8_t memory[MEMORY_SEGMENT_COUNT][MEMORY_SEGMENT_SIZE])
{
    switch(instr->opcode)
    {
        case EXT:
            switch(instr->arg0)
            {
                case EXT_HALT:
                    printf("Exiting at halt instruction (instruction %ld)\n", (cpu->pc - cpu->code));
                    exit(0);
                    break;
                case EXT_CPY:
                    cpu->regs[instr->arg1] = cpu->regs[instr->arg2];
                    break;
                case EXT_NOT:
                    cpu->regs[instr->arg1] = ~(cpu->regs[instr->arg2]);
                    break;
                case EXT_LSL:
                    cpu->regs[instr->arg1] = cpu->regs[instr->arg1] << cpu->regs[instr->arg2];
                    break;
                case EXT_LSR:
                    cpu->regs[instr->arg1] = cpu->regs[instr->arg1] >> cpu->regs[instr->arg2];
                    break;
                case EXT_JMP:
                    cpu->pc = cpu->code + (cpu->regs[instr->arg1] * JUMP_SEGMENT_SIZE) + cpu->regs[instr->arg2] - 1;
                    break;
                case EXT_NOP:
                    break;
                case EXT_BRKP:
                    if (cpu->debugMode)
                    {
                        cpu->breakState = 1;
                        printf("Entering break state\n");
                    }
                    break;
            }
            break;
        case ADD:
            cpu->regs[instr->arg0] = cpu->regs[instr->arg1] + cpu->regs[instr->arg2];
            break;
        case SUB:
            cpu->regs[instr->arg0] = cpu->regs[instr->arg1] - cpu->regs[instr->arg2];
            break;
        case ADDC:
            cpu->regs[instr->arg0] += ((instr->arg1 << 4) & 0x00F0) + instr->arg2;
            break;
        case SUBC:
            cpu->regs[instr->arg0] -= ((instr->arg1 << 4) & 0x00F0) + instr->arg2;
            break;
        case CMP:
            if (cpu->regs[instr->arg1] < cpu->regs[instr->arg2])
                cpu->regs[instr->arg0] = 0;
            else if (cpu->regs[instr->arg1] > cpu->regs[instr->arg2])
                cpu->regs[instr->arg0] = 2;
            else
                cpu->regs[instr->arg0] = 1;
            break;
        case JLT:
            if (cpu->regs[instr->arg0] == 0)
                cpu->pc = cpu->code + (cpu->regs[instr->arg1] * JUMP_SEGMENT_SIZE) + cpu->regs[instr->arg2] - 1;
            break;
        case JGT:
            if (cpu->regs[instr->arg0] == 2)
                cpu->pc = cpu->code + (cpu->regs[instr->arg1] * JUMP_SEGMENT_SIZE) + cpu->regs[instr->arg2] - 1;
            break;
        case JEQ:
            if (cpu->regs[instr->arg0] == 1)
                cpu->pc = cpu->code + (cpu->regs[instr->arg1] * JUMP_SEGMENT_SIZE) + cpu->regs[instr->arg2] - 1;
            break;
        case LDR:
            cpu->regs[instr->arg0] = memory[cpu->regs[instr->arg1]][cpu->regs[instr->arg2]];
            break;
        case STR:
            if (cpu->regs[instr->arg1] < 128) // Segment is not part of ROM
                memory[cpu->regs[instr->arg1]][cpu->regs[instr->arg2]] = cpu->regs[instr->arg0];
            else
            {
                printf("Attempted illegal write to ROM\n");
                exit(1);
            }
            break;
        case LRC:
            cpu->regs[instr->arg0] = ((instr->arg1 << 4) & 0x00F0) + instr->arg2;
            break;
        case AND:
            cpu->regs[instr->arg0] = cpu->regs[instr->arg1] & cpu->regs[instr->arg2];
            break;
        case OR:
            cpu->regs[instr->arg0] = cpu->regs[instr->arg1] | cpu->regs[instr->arg2];
            break;
        case XOR:
            cpu->regs[instr->arg0] = cpu->regs[instr->arg1] ^ cpu->regs[instr->arg2];
            break;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x10(%rbp), %rax
movzwl (%rax), %eax
andl $0xf, %eax
movq %rax, -0x20(%rbp)
subw $0xe, %ax
ja 0x3e2b
movq -0x20(%rbp), %rax
leaq 0x1b79(%rip), %rcx      # 0x51a0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rax
movzwl (%rax), %ecx
shrl $0x4, %ecx
andl $0xf, %ecx
movw %cx, %ax
movq %rcx, -0x28(%rbp)
subw $0x7, %ax
ja 0x3835
movq -0x28(%rbp), %rax
leaq 0x1b83(%rip), %rcx      # 0x51dc
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rsi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
subq %rax, %rsi
sarq %rsi
leaq 0x1d08(%rip), %rdi      # 0x5387
movb $0x0, %al
callq 0x1040
xorl %edi, %edi
callq 0x1170
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0xc, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movb (%rax,%rcx), %dl
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x8, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x3835
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0xc, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
xorl $-0x1, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x8, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x3835
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x8, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
movq -0x8(%rbp), %rcx
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0xc, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rcx,%rdx), %ecx
shll %cl, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x8, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x3835
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x8, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
movq -0x8(%rbp), %rcx
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0xc, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rcx,%rdx), %ecx
sarl %cl, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x8, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x3835
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0x8, %dx
andw $0xf, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rax,%rdx), %eax
shll $0x8, %eax
cltq
shlq %rax
addq %rax, %rcx
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0xc, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rax,%rdx), %eax
cltq
shlq %rax
addq %rax, %rcx
addq $-0x2, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10(%rax)
jmp 0x3835
jmp 0x3835
movq -0x8(%rbp), %rax
cmpl $0x0, 0x20(%rax)
je 0x3833
movq -0x8(%rbp), %rax
movl $0x1, 0x24(%rax)
leaq 0x18c8(%rip), %rdi      # 0x50f4
movb $0x0, %al
callq 0x1040
jmp 0x3835
jmp 0x3e2b
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x8, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
movq -0x8(%rbp), %rcx
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0xc, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rcx,%rdx), %ecx
addl %ecx, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x4, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x3e2b
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x8, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
movq -0x8(%rbp), %rcx
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0xc, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rcx,%rdx), %ecx
subl %ecx, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x4, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x3e2b
movq -0x10(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %esi
shll $0x4, %esi
andl $0xf0, %esi
movq -0x10(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %eax
addl %eax, %esi
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x4, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %edx
addl %esi, %edx
movb %dl, (%rax,%rcx)
jmp 0x3e2b
movq -0x10(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %esi
shll $0x4, %esi
andl $0xf0, %esi
movq -0x10(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %eax
addl %eax, %esi
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x4, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %edx
subl %esi, %edx
movb %dl, (%rax,%rcx)
jmp 0x3e2b
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x8, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
movq -0x8(%rbp), %rcx
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0xc, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rcx,%rdx), %ecx
cmpl %ecx, %eax
jge 0x39e2
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x4, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movb $0x0, (%rax,%rcx)
jmp 0x3a56
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x8, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
movq -0x8(%rbp), %rcx
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0xc, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rcx,%rdx), %ecx
cmpl %ecx, %eax
jle 0x3a38
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x4, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movb $0x2, (%rax,%rcx)
jmp 0x3a54
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x4, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movb $0x1, (%rax,%rcx)
jmp 0x3a56
jmp 0x3e2b
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x4, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0x3ad7
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0x8, %dx
andw $0xf, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rax,%rdx), %eax
shll $0x8, %eax
cltq
shlq %rax
addq %rax, %rcx
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0xc, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rax,%rdx), %eax
cltq
shlq %rax
addq %rax, %rcx
addq $-0x2, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10(%rax)
jmp 0x3e2b
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x4, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
cmpl $0x2, %eax
jne 0x3b58
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0x8, %dx
andw $0xf, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rax,%rdx), %eax
shll $0x8, %eax
cltq
shlq %rax
addq %rax, %rcx
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0xc, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rax,%rdx), %eax
cltq
shlq %rax
addq %rax, %rcx
addq $-0x2, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10(%rax)
jmp 0x3e2b
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x4, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
cmpl $0x1, %eax
jne 0x3bd9
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0x8, %dx
andw $0xf, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rax,%rdx), %eax
shll $0x8, %eax
cltq
shlq %rax
addq %rax, %rcx
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0xc, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rax,%rdx), %eax
cltq
shlq %rax
addq %rax, %rcx
addq $-0x2, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10(%rax)
jmp 0x3e2b
movq -0x18(%rbp), %rax
movq -0x8(%rbp), %rcx
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0x8, %dx
andw $0xf, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rcx,%rdx), %ecx
shlq $0x8, %rcx
addq %rcx, %rax
movq -0x8(%rbp), %rcx
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0xc, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rcx,%rdx), %ecx
movb (%rax,%rcx), %dl
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x4, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x3e2b
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x8, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
cmpl $0x80, %eax
jge 0x3cc2
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x4, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movb (%rax,%rcx), %dl
movq -0x18(%rbp), %rax
movq -0x8(%rbp), %rcx
movq -0x10(%rbp), %rsi
movw (%rsi), %si
shrw $0x8, %si
andw $0xf, %si
movzwl %si, %esi
movl %esi, %esi
movzbl (%rcx,%rsi), %ecx
shlq $0x8, %rcx
addq %rcx, %rax
movq -0x8(%rbp), %rcx
movq -0x10(%rbp), %rsi
movw (%rsi), %si
shrw $0xc, %si
movzwl %si, %esi
movl %esi, %esi
movzbl (%rcx,%rsi), %ecx
movb %dl, (%rax,%rcx)
jmp 0x3cda
leaq 0x16ed(%rip), %rdi      # 0x53b6
movb $0x0, %al
callq 0x1040
movl $0x1, %edi
callq 0x1170
jmp 0x3e2b
movq -0x10(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %eax
shll $0x4, %eax
andl $0xf0, %eax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0xc, %cx
movzwl %cx, %ecx
addl %ecx, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x4, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x3e2b
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x8, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
movq -0x8(%rbp), %rcx
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0xc, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rcx,%rdx), %ecx
andl %ecx, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x4, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x3e2b
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x8, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
movq -0x8(%rbp), %rcx
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0xc, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rcx,%rdx), %ecx
orl %ecx, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x4, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x3e2b
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x8, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
movq -0x8(%rbp), %rcx
movq -0x10(%rbp), %rdx
movw (%rdx), %dx
shrw $0xc, %dx
movzwl %dx, %edx
movl %edx, %edx
movzbl (%rcx,%rdx), %ecx
xorl %ecx, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movw (%rcx), %cx
shrw $0x4, %cx
andw $0xf, %cx
movzwl %cx, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
addq $0x30, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)