// File: /workspace/github_c_makefile_star2_O3/yutopp[P]cc/ir.c
// Function: ir_inst_fprint
void ir_inst_fprint(FILE* fp, IRInst* inst) {
    switch(inst->kind) {
    case IR_INST_KIND_LET:
        fprintf(fp, "%%%ld = ", inst->value.let.id);
        switch(inst->value.let.rhs.kind) {
        case IR_INST_VALUE_KIND_SYMBOL:
        {
            fprintf(fp, "SYMBOL %s", inst->value.let.rhs.value.symbol);
            break;
        }

        case IR_INST_VALUE_KIND_STRING:
        {
            fprintf(fp, "\"%s\"", inst->value.let.rhs.value.string);
            break;
        }

        case IR_INST_VALUE_KIND_REF:
        {
            if (inst->value.let.rhs.value.ref.is_global) {
                fprintf(fp, "g@");
            }
            fprintf(fp, "%ld", inst->value.let.rhs.value.ref.sym);
            break;
        }

        case IR_INST_VALUE_KIND_ADDR_OF:
        {
            fprintf(fp, "&%ld", inst->value.let.rhs.value.addr_of.sym);
            break;
        }

        case IR_INST_VALUE_KIND_IMM_INT:
        {
            fprintf(fp, "%d", inst->value.let.rhs.value.imm_int);
            break;
        }

        case IR_INST_VALUE_KIND_OP_BIN:
        {
            char const* op_buf = token_to_string(inst->value.let.rhs.value.op_bin.op);
            fprintf(fp, "%s %%%ld %%%ld",
                    op_buf,
                    inst->value.let.rhs.value.op_bin.lhs,
                    inst->value.let.rhs.value.op_bin.rhs);
            free((char*)op_buf);
            break;
        }

        case IR_INST_VALUE_KIND_CALL:
        {
            fprintf(fp, "call %%%ld", inst->value.let.rhs.value.call.lhs);
            Vector* args = inst->value.let.rhs.value.call.args;
            for(size_t i=0; i<vector_len(args); ++i) {
                IRSymbolID* sym = (IRSymbolID*)vector_at(args, i);
                fprintf(fp, " %%%ld", *sym);
            }
            break;
        }

        default:
            assert(0); // TODO: error handling
        }
        fprintf(fp, "\n");
        break;

    case IR_INST_KIND_RET:
        fprintf(fp, "RET %%%ld\n", inst->value.ret.id);
        break;

    case IR_INST_KIND_BRANCH:
        fprintf(fp, "BR %%%ld: ", inst->value.branch.cond);
        fprintf(fp, "then -> %ld, ", inst->value.branch.then_bb->id);
        fprintf(fp, "else -> %ld\n", inst->value.branch.else_bb->id);

        break;

    case IR_INST_KIND_JUMP:
        fprintf(fp, "JUMP -> %ld\n", inst->value.jump.next_bb->id);
        break;

    default:
        assert(0); // TODO: error handling
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movl (%rsi), %eax
cmpq $0x3, %rax
ja 0x3ad4
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x3b75(%rip), %rcx      # 0x7480
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x8(%r14), %rdx
leaq 0x3c0e(%rip), %rsi      # 0x752d
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1120
movl 0x10(%r14), %eax
cmpq $0x6, %rax
ja 0x3af3
leaq 0x3b52(%rip), %rcx      # 0x7490
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x18(%r14), %rdx
leaq 0x3be4(%rip), %rsi      # 0x7536
jmp 0x3a20
movq 0x8(%r14), %rdx
leaq 0x3c31(%rip), %rsi      # 0x7593
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1120
movq 0x10(%r14), %rax
movq (%rax), %rdx
leaq 0x3c24(%rip), %rsi      # 0x759e
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1120
movq 0x18(%r14), %rax
movq (%rax), %rdx
leaq 0x3c1a(%rip), %rsi      # 0x75ac
jmp 0x39af
movq 0x8(%r14), %rax
movq (%rax), %rdx
leaq 0x3c17(%rip), %rsi      # 0x75b9
jmp 0x39af
movq 0x8(%r14), %rdx
leaq 0x3bd9(%rip), %rsi      # 0x7588
movq %rbx, %rdi
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x1120
movl 0x18(%r14), %edx
leaq 0x3f86(%rip), %rsi      # 0x7955
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1120
jmp 0x3a2a
cmpl $0x0, 0x18(%r14)
je 0x39fb
leaq 0x3b57(%rip), %rdi      # 0x7540
movl $0x2, %esi
movl $0x1, %edx
movq %rbx, %rcx
callq 0x11c0
movq 0x20(%r14), %rdx
leaq 0x3b4d(%rip), %rsi      # 0x7553
jmp 0x3a20
movq 0x18(%r14), %rdx
leaq 0x3b30(%rip), %rsi      # 0x7543
jmp 0x3a20
movq 0x18(%r14), %rdx
leaq 0x3a49(%rip), %rsi      # 0x7469
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1120
movl $0xa, %edi
movq %rbx, %rsi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x10f0
movq 0x18(%r14), %rdi
callq 0x1b54
movq %rax, %r15
movq 0x20(%r14), %rcx
movq 0x28(%r14), %r8
leaq 0x3aeb(%rip), %rsi      # 0x7548
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x1120
movq %r15, %rdi
callq 0x1040
jmp 0x3a2a
movq 0x18(%r14), %rdx
leaq 0x3ad8(%rip), %rsi      # 0x7557
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1120
movq 0x20(%r14), %r14
movq %r14, %rdi
callq 0x2f0b
testq %rax, %rax
je 0x3a2a
leaq 0x3aaf(%rip), %r15      # 0x7550
xorl %r12d, %r12d
movq %r14, %rdi
movq %r12, %rsi
callq 0x2ef6
movq (%rax), %rdx
movq %rbx, %rdi
movq %r15, %rsi
xorl %eax, %eax
callq 0x1120
incq %r12
movq %r14, %rdi
callq 0x2f0b
cmpq %rax, %r12
jb 0x3aa4
jmp 0x3a2a
leaq 0x3d63(%rip), %rdi      # 0x783e
leaq 0x39ee(%rip), %rsi      # 0x74d0
leaq 0x3a79(%rip), %rcx      # 0x7562
movl $0x2a2, %edx            # imm = 0x2A2
callq 0x10d0
leaq 0x3d44(%rip), %rdi      # 0x783e
leaq 0x39cf(%rip), %rsi      # 0x74d0
leaq 0x3a5a(%rip), %rcx      # 0x7562
movl $0x28d, %edx            # imm = 0x28D
callq 0x10d0