// File: /workspace/github_c_makefile_star2_O1/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 0x3e04
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x3835(%rip), %rcx      # 0x7470
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x8(%r14), %rdx
leaq 0x38ce(%rip), %rsi      # 0x751d
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1110
movl 0x10(%r14), %eax
cmpq $0x6, %rax
ja 0x3e23
leaq 0x3812(%rip), %rcx      # 0x7480
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x18(%r14), %rdx
leaq 0x38a4(%rip), %rsi      # 0x7526
jmp 0x3d50
movq 0x8(%r14), %rdx
leaq 0x38f1(%rip), %rsi      # 0x7583
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1110
movq 0x10(%r14), %rax
movq (%rax), %rdx
leaq 0x38e4(%rip), %rsi      # 0x758e
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1110
movq 0x18(%r14), %rax
movq (%rax), %rdx
leaq 0x38da(%rip), %rsi      # 0x759c
jmp 0x3cdf
movq 0x8(%r14), %rax
movq (%rax), %rdx
leaq 0x38d7(%rip), %rsi      # 0x75a9
jmp 0x3cdf
movq 0x8(%r14), %rdx
leaq 0x3899(%rip), %rsi      # 0x7578
movq %rbx, %rdi
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x1110
movl 0x18(%r14), %edx
leaq 0x3c46(%rip), %rsi      # 0x7945
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1110
jmp 0x3d5a
cmpl $0x0, 0x18(%r14)
je 0x3d2b
leaq 0x3817(%rip), %rdi      # 0x7530
movl $0x2, %esi
movl $0x1, %edx
movq %rbx, %rcx
callq 0x11b0
movq 0x20(%r14), %rdx
leaq 0x380d(%rip), %rsi      # 0x7543
jmp 0x3d50
movq 0x18(%r14), %rdx
leaq 0x37f0(%rip), %rsi      # 0x7533
jmp 0x3d50
movq 0x18(%r14), %rdx
leaq 0x3709(%rip), %rsi      # 0x7459
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1110
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 0x37ab(%rip), %rsi      # 0x7538
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x1110
movq %r15, %rdi
callq 0x1040
jmp 0x3d5a
movq 0x18(%r14), %rdx
leaq 0x3798(%rip), %rsi      # 0x7547
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1110
movq 0x20(%r14), %r14
movq %r14, %rdi
callq 0x322b
testq %rax, %rax
je 0x3d5a
leaq 0x376f(%rip), %r15      # 0x7540
xorl %r12d, %r12d
movq %r14, %rdi
movq %r12, %rsi
callq 0x3216
movq (%rax), %rdx
movq %rbx, %rdi
movq %r15, %rsi
xorl %eax, %eax
callq 0x1110
incq %r12
movq %r14, %rdi
callq 0x322b
cmpq %rax, %r12
jb 0x3dd4
jmp 0x3d5a
leaq 0x3a23(%rip), %rdi      # 0x782e
leaq 0x36ae(%rip), %rsi      # 0x74c0
leaq 0x3739(%rip), %rcx      # 0x7552
movl $0x2a2, %edx            # imm = 0x2A2
callq 0x10d0
leaq 0x3a04(%rip), %rdi      # 0x782e
leaq 0x368f(%rip), %rsi      # 0x74c0
leaq 0x371a(%rip), %rcx      # 0x7552
movl $0x28d, %edx            # imm = 0x28D
callq 0x10d0