// File: /workspace/github_c_makefile_star2_O0/jtuu[P]quesler/src/debug.c
// Function: disassemble_instruction
size_t disassemble_instruction(Chunk* chunk, size_t offset, bool line_info) {
    for (size_t i = 0; i < chunk->labels_count; i++) {
        if (chunk->labels[i] == (int32_t) offset) {
            printf("%ld:\n", i);
            break;
        }
    }

    if (line_info) {
        printf("%04ld ", offset);

        if (offset > 0 && chunk->lines[offset] == chunk->lines[offset - 1]) {
            printf("   | ");
        } else {
            printf("%4ld ", chunk->lines[offset]);
        }
    } else {
        printf("    ");
    }

    size_t opcode_size = 1;
    size_t args_size = 0;

    uint16_t opcode = chunk->code[offset];
    
    if (opcode == EXTENDED_OPCODE_TABLE1 ||
            opcode == EXTENDED_OPCODE_TABLE2) {
        opcode_size = 2;
        opcode = (uint16_t) READ2(&chunk->code[offset]);
    }

    const OpcodeDefinition* opcode_def = get_opcode_definition(opcode);

    if (opcode_def == NULL) {
        fprintf(stderr, "Disassembler: Unknown opcode 0x%hx at offset 0x%08lx\n", opcode, offset);
        printf("unknown%hx", opcode);
        goto done;
    }

    printf("%s", opcode_def->name);

    uint8_t* arg = &chunk->code[offset + opcode_size];

    for (size_t i = 0; i < OPCODE_MAX_ARITY; i++) {
        ParameterType param_type = opcode_def->parameters[i];

        if (param_type == T_NONE || param_type == T_ARGS) {
            break;
        } else if (param_type == T_IMED || param_type == T_PUSH) {
            continue;
        } else {
            if (i < 2) {
                printf(" ");
            } else {
                printf(", ");
            }

            switch (param_type) {
                case T_REG:
                case T_BREG:
                    printf("R%hhu", *arg);
                    break;
                case T_DWORD:
                    printf("%d", READ4(arg));
                    break;
                case T_STR: {
                    uint16_t* str_start = (uint16_t*) arg;
                    uint16_t* str_end = (uint16_t*) arg;
                    
                    printf("\"");
                    while (*str_end != 0) {
                        printf("%lc", (wchar_t) *str_end);
                        str_end++;
                    }
                    printf("\"");

                    size_t str_size = (size_t) (str_end - str_start + 1) * 2;
                    args_size += str_size;
                    arg += str_size;
                    break;
                }
                case T_FUNC: {
                    size_t label = (size_t) READ2(arg);
                    int32_t label_offset = chunk->labels[label];
                    printf("%lu (%d)", label, label_offset);
                    break;
                }
                default:
                    fprintf(stderr, "Disassembler: Unknown parameter type %u\n", param_type);
                    goto done;
            }
        }

        if (!is_variable_sized(param_type)) {
            size_t param_size = get_parameter_size(param_type);
            args_size += param_size;
            arg += param_size;
        }
    }

done:
    printf("\n");
    return offset + opcode_size + args_size;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movb %dl, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
andb $0x1, %al
movb %al, -0x11(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x40(%rcx), %rax
jae 0x73fb
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rax
movq -0x20(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movq -0x10(%rbp), %rcx
cmpl %ecx, %eax
jne 0x73eb
movq -0x20(%rbp), %rsi
leaq 0x527f(%rip), %rdi      # 0xc661
movb $0x0, %al
callq 0x4090
jmp 0x73fb
jmp 0x73ed
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x73b2
testb $0x1, -0x11(%rbp)
je 0x7470
movq -0x10(%rbp), %rsi
leaq 0x525b(%rip), %rdi      # 0xc667
movb $0x0, %al
callq 0x4090
cmpq $0x0, -0x10(%rbp)
jbe 0x7450
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq -0x8(%rbp), %rcx
movq 0x18(%rcx), %rcx
movq -0x10(%rbp), %rdx
subq $0x1, %rdx
cmpq (%rcx,%rdx,8), %rax
jne 0x7450
leaq 0x5227(%rip), %rdi      # 0xc66e
movb $0x0, %al
callq 0x4090
jmp 0x746e
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
leaq 0x520d(%rip), %rdi      # 0xc674
movb $0x0, %al
callq 0x4090
jmp 0x747e
leaq 0x5203(%rip), %rdi      # 0xc67a
movb $0x0, %al
callq 0x4090
movq $0x1, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x10(%rbp), %rcx
movzbl (%rax,%rcx), %eax
movw %ax, -0x32(%rbp)
movzwl -0x32(%rbp), %eax
cmpl $0xf8, %eax
je 0x74b8
movzwl -0x32(%rbp), %eax
cmpl $0xf9, %eax
jne 0x74ea
movq $0x2, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x10(%rbp), %rcx
movzbl (%rax,%rcx), %eax
shll $0x8, %eax
movq -0x8(%rbp), %rcx
movq 0x10(%rcx), %rcx
movq -0x10(%rbp), %rdx
movzbl 0x1(%rcx,%rdx), %ecx
orl %ecx, %eax
movw %ax, -0x32(%rbp)
movzwl -0x32(%rbp), %edi
callq 0x7bf0
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0x7535
movq 0x11aeb(%rip), %rax     # 0x18ff0
movq (%rax), %rdi
movzwl -0x32(%rbp), %edx
movq -0x10(%rbp), %rcx
leaq 0x5168(%rip), %rsi      # 0xc67f
movb $0x0, %al
callq 0x40f0
movzwl -0x32(%rbp), %esi
leaq 0x518c(%rip), %rdi      # 0xc6b5
movb $0x0, %al
callq 0x4090
jmp 0x7795
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0x517c(%rip), %rdi      # 0xc6c0
movb $0x0, %al
callq 0x4090
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x10(%rbp), %rcx
addq -0x28(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movq $0x0, -0x50(%rbp)
cmpq $0xb, -0x50(%rbp)
jae 0x7793
movq -0x40(%rbp), %rax
movq -0x50(%rbp), %rcx
movl 0x10(%rax,%rcx,4), %eax
movl %eax, -0x54(%rbp)
cmpl $0x0, -0x54(%rbp)
je 0x7590
cmpl $0x1, -0x54(%rbp)
jne 0x7595
jmp 0x7793
cmpl $0x9, -0x54(%rbp)
je 0x75a1
cmpl $0xc, -0x54(%rbp)
jne 0x75a6
jmp 0x7782
cmpq $0x2, -0x50(%rbp)
jae 0x75bd
leaq 0x50c9(%rip), %rdi      # 0xc67d
movb $0x0, %al
callq 0x4090
jmp 0x75cb
leaq 0x50ff(%rip), %rdi      # 0xc6c3
movb $0x0, %al
callq 0x4090
movl -0x54(%rbp), %eax
addl $-0x2, %eax
movl %eax, %ecx
movq %rcx, -0x90(%rbp)
subl $0x11, %eax
ja 0x7726
movq -0x90(%rbp), %rax
leaq 0x501f(%rip), %rcx      # 0xc610
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x48(%rbp), %rax
movzbl (%rax), %esi
leaq 0x50be(%rip), %rdi      # 0xc6c6
movb $0x0, %al
callq 0x4090
jmp 0x7743
movq -0x48(%rbp), %rax
movzbl (%rax), %esi
shll $0x18, %esi
movq -0x48(%rbp), %rax
movzbl 0x1(%rax), %eax
shll $0x10, %eax
orl %eax, %esi
movq -0x48(%rbp), %rax
movzbl 0x2(%rax), %eax
shll $0x8, %eax
orl %eax, %esi
movq -0x48(%rbp), %rax
movzbl 0x3(%rax), %eax
orl %eax, %esi
leaq 0x4c45(%rip), %rdi      # 0xc28e
movb $0x0, %al
callq 0x4090
jmp 0x7743
movq -0x48(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x68(%rbp)
leaq 0x4e05(%rip), %rdi      # 0xc471
movb $0x0, %al
callq 0x4090
movq -0x68(%rbp), %rax
movzwl (%rax), %eax
cmpl $0x0, %eax
je 0x76a2
movq -0x68(%rbp), %rax
movzwl (%rax), %esi
leaq 0x503f(%rip), %rdi      # 0xc6cc
movb $0x0, %al
callq 0x4090
movq -0x68(%rbp), %rax
addq $0x2, %rax
movq %rax, -0x68(%rbp)
jmp 0x7673
leaq 0x4dc8(%rip), %rdi      # 0xc471
movb $0x0, %al
callq 0x4090
movq -0x68(%rbp), %rax
movq -0x60(%rbp), %rcx
subq %rcx, %rax
sarq %rax
addq $0x1, %rax
shlq %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x70(%rbp), %rax
addq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
jmp 0x7743
movq -0x48(%rbp), %rax
movzbl (%rax), %eax
shll $0x8, %eax
movq -0x48(%rbp), %rcx
movzbl 0x1(%rcx), %ecx
orl %ecx, %eax
cltq
movq %rax, -0x78(%rbp)
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rax
movq -0x78(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x7c(%rbp)
movq -0x78(%rbp), %rsi
movl -0x7c(%rbp), %edx
leaq 0x4fb3(%rip), %rdi      # 0xc6d0
movb $0x0, %al
callq 0x4090
jmp 0x7743
movq 0x118c3(%rip), %rax     # 0x18ff0
movq (%rax), %rdi
movl -0x54(%rbp), %edx
leaq 0x4f9f(%rip), %rsi      # 0xc6d9
movb $0x0, %al
callq 0x40f0
jmp 0x7795
jmp 0x7745
jmp 0x7747
movl -0x54(%rbp), %edi
callq 0x7ce0
testb $0x1, %al
jne 0x7780
movl -0x54(%rbp), %edi
callq 0x7d00
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x88(%rbp), %rax
addq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
jmp 0x7782
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x756a
jmp 0x7795
leaq 0x6b74(%rip), %rdi      # 0xe310
movb $0x0, %al
callq 0x4090
movq -0x10(%rbp), %rax
addq -0x28(%rbp), %rax
addq -0x30(%rbp), %rax
addq $0x90, %rsp
popq %rbp
retq
nopl (%rax,%rax)