// File: /workspace/github_c_makefile_star2_O0/minkcv[P]vm/machine/cpu.c
// Function: disassemble
void disassemble(Instruction* instr, char* assembly)
{
    // If the instructions reads the last 2 arguments as a constant
    uint8_t constant = ((instr->arg1 << 4) & 0x00F0) + instr->arg2;
    switch(instr->opcode)
    {
        case EXT:
            switch(instr->arg0)
            {
                case EXT_HALT:
                    sprintf(assembly, "HALT");
                    break;
                case EXT_CPY:
                    sprintf(assembly, "CPY r%02d r%02d", instr->arg1, instr->arg2);
                    break;
                case EXT_NOT:
                    sprintf(assembly, "NOT %02d %02d", instr->arg1, instr->arg2);
                    break;
                case EXT_LSL:
                    sprintf(assembly, "LSL r%02d r%02d", instr->arg1, instr->arg2);
                    break;
                case EXT_LSR:
                    sprintf(assembly, "LSR r%02d r%02d", instr->arg1, instr->arg2);
                    break;
                case EXT_JMP:
                    sprintf(assembly, "JMP r%02d r%02d", instr->arg1, instr->arg2);
                    break;
                case EXT_NOP:
                    sprintf(assembly, "NOP");
                    break;
                case EXT_BRKP:
                    sprintf(assembly, "BRKP");
                    break;
            }
            break;
        case ADD:
            sprintf(assembly, "ADD r%02d r%02d r%02d", instr->arg0, instr->arg1, instr->arg2);
            break;
        case SUB:
            sprintf(assembly, "SUB r%02d r%02d r%02d", instr->arg0, instr->arg1, instr->arg2);
            break;
        case ADDC:
            sprintf(assembly, "ADDC r%02d #%03d ; (0x%04X)", instr->arg0, constant, constant);
            break;
        case SUBC:
            sprintf(assembly, "SUBC r%02d #%03d ; (0x%04X)", instr->arg0, constant, constant);
            break;
        case CMP:
            sprintf(assembly, "CMP r%02d r%02d r%02d", instr->arg0, instr->arg1, instr->arg2);
            break;
        case JLT:
            sprintf(assembly, "JLT r%02d r%02d r%02d", instr->arg0, instr->arg1, instr->arg2);
            break;
        case JGT:
            sprintf(assembly, "JGT r%02d r%02d r%02d", instr->arg0, instr->arg1, instr->arg2);
            break;
        case JEQ:
            sprintf(assembly, "JEQ r%02d r%02d r%02d", instr->arg0, instr->arg1, instr->arg2);
            break;
        case LDR:
            sprintf(assembly, "LDR r%02d r%02d r%02d", instr->arg0, instr->arg1, instr->arg2);
            break;
        case STR:
            sprintf(assembly, "STR r%02d r%02d r%02d", instr->arg0, instr->arg1, instr->arg2);
            break;
        case LRC:
            sprintf(assembly, "LRC r%02d #%03d ; (0x%04X)", instr->arg0, constant, constant);
            break;
        case AND:
            sprintf(assembly, "AND r%02d r%02d r%02d", instr->arg0, instr->arg1, instr->arg2);
            break;
        case OR:
            sprintf(assembly, "OR r%02d r%02d r%02d", instr->arg0, instr->arg1, instr->arg2);
            break;
        case XOR:
            sprintf(assembly, "XOR r%02d r%02d r%02d", instr->arg0, instr->arg1, instr->arg2);
            break;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movzwl (%rax), %ecx
movl %ecx, %eax
shrl $0x4, %eax
andl $0xf0, %eax
shrl $0xc, %ecx
orl %ecx, %eax
movb %al, -0x11(%rbp)
movq -0x8(%rbp), %rax
movzwl (%rax), %eax
andl $0xf, %eax
movq %rax, -0x20(%rbp)
subw $0xe, %ax
ja 0x3522
movq -0x20(%rbp), %rax
leaq 0x2168(%rip), %rcx      # 0x5144
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x8(%rbp), %rax
movzwl (%rax), %ecx
shrl $0x4, %ecx
andl $0xf, %ecx
movw %cx, %ax
movq %rcx, -0x28(%rbp)
subw $0x7, %ax
ja 0x3161
movq -0x28(%rbp), %rax
leaq 0x2172(%rip), %rcx      # 0x5180
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rdi
leaq 0x21da(%rip), %rsi      # 0x51fc
movb $0x0, %al
callq 0x1080
jmp 0x3161
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %edx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %ecx
leaq 0x21a8(%rip), %rsi      # 0x5201
movb $0x0, %al
callq 0x1080
jmp 0x3161
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %edx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %ecx
leaq 0x2181(%rip), %rsi      # 0x5211
movb $0x0, %al
callq 0x1080
jmp 0x3161
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %edx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %ecx
leaq 0x2158(%rip), %rsi      # 0x521f
movb $0x0, %al
callq 0x1080
jmp 0x3161
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %edx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %ecx
leaq 0x2131(%rip), %rsi      # 0x522f
movb $0x0, %al
callq 0x1080
jmp 0x3161
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %edx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %ecx
leaq 0x210d(%rip), %rsi      # 0x523f
movb $0x0, %al
callq 0x1080
jmp 0x3161
movq -0x10(%rbp), %rdi
leaq 0x2109(%rip), %rsi      # 0x524f
movb $0x0, %al
callq 0x1080
jmp 0x3161
movq -0x10(%rbp), %rdi
leaq 0x20f9(%rip), %rsi      # 0x5253
movb $0x0, %al
callq 0x1080
jmp 0x3522
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x4, %ax
andw $0xf, %ax
movzwl %ax, %edx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %ecx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %r8d
leaq 0x20b4(%rip), %rsi      # 0x5258
movb $0x0, %al
callq 0x1080
jmp 0x3522
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x4, %ax
andw $0xf, %ax
movzwl %ax, %edx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %ecx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %r8d
leaq 0x2080(%rip), %rsi      # 0x526e
movb $0x0, %al
callq 0x1080
jmp 0x3522
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x4, %ax
andw $0xf, %ax
movzwl %ax, %edx
movzbl -0x11(%rbp), %ecx
movzbl -0x11(%rbp), %r8d
leaq 0x2064(%rip), %rsi      # 0x5284
movb $0x0, %al
callq 0x1080
jmp 0x3522
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x4, %ax
andw $0xf, %ax
movzwl %ax, %edx
movzbl -0x11(%rbp), %ecx
movzbl -0x11(%rbp), %r8d
leaq 0x204e(%rip), %rsi      # 0x52a0
movb $0x0, %al
callq 0x1080
jmp 0x3522
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x4, %ax
andw $0xf, %ax
movzwl %ax, %edx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %ecx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %r8d
leaq 0x2020(%rip), %rsi      # 0x52bc
movb $0x0, %al
callq 0x1080
jmp 0x3522
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x4, %ax
andw $0xf, %ax
movzwl %ax, %edx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %ecx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %r8d
leaq 0x1fec(%rip), %rsi      # 0x52d2
movb $0x0, %al
callq 0x1080
jmp 0x3522
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x4, %ax
andw $0xf, %ax
movzwl %ax, %edx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %ecx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %r8d
leaq 0x1fb8(%rip), %rsi      # 0x52e8
movb $0x0, %al
callq 0x1080
jmp 0x3522
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x4, %ax
andw $0xf, %ax
movzwl %ax, %edx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %ecx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %r8d
leaq 0x1f84(%rip), %rsi      # 0x52fe
movb $0x0, %al
callq 0x1080
jmp 0x3522
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x4, %ax
andw $0xf, %ax
movzwl %ax, %edx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %ecx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %r8d
leaq 0x1f50(%rip), %rsi      # 0x5314
movb $0x0, %al
callq 0x1080
jmp 0x3522
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x4, %ax
andw $0xf, %ax
movzwl %ax, %edx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %ecx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %r8d
leaq 0x1f1c(%rip), %rsi      # 0x532a
movb $0x0, %al
callq 0x1080
jmp 0x3522
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x4, %ax
andw $0xf, %ax
movzwl %ax, %edx
movzbl -0x11(%rbp), %ecx
movzbl -0x11(%rbp), %r8d
leaq 0x1f00(%rip), %rsi      # 0x5340
movb $0x0, %al
callq 0x1080
jmp 0x3522
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x4, %ax
andw $0xf, %ax
movzwl %ax, %edx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %ecx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %r8d
leaq 0x1ed1(%rip), %rsi      # 0x535b
movb $0x0, %al
callq 0x1080
jmp 0x3522
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x4, %ax
andw $0xf, %ax
movzwl %ax, %edx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %ecx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %r8d
leaq 0x1e9e(%rip), %rsi      # 0x5372
movb $0x0, %al
callq 0x1080
jmp 0x3522
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x4, %ax
andw $0xf, %ax
movzwl %ax, %edx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %ecx
movq -0x8(%rbp), %rax
movw (%rax), %ax
shrw $0xc, %ax
movzwl %ax, %r8d
leaq 0x1e56(%rip), %rsi      # 0x5371
movb $0x0, %al
callq 0x1080
addq $0x30, %rsp
popq %rbp
retq
nopl (%rax,%rax)