// File: /workspace/github_c_makefile_star2_O2/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 0x34aa
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x3189(%rip), %rcx      # 0x6480
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x8(%r14), %rdx
leaq 0x3222(%rip), %rsi      # 0x652d
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1120
movl 0x10(%r14), %eax
cmpq $0x6, %rax
ja 0x34c9
leaq 0x3166(%rip), %rcx      # 0x6490
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x18(%r14), %rdx
leaq 0x31f8(%rip), %rsi      # 0x6536
jmp 0x3408
movq 0x8(%r14), %rdx
leaq 0x3245(%rip), %rsi      # 0x6593
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1120
movq 0x10(%r14), %rax
movq (%rax), %rdx
leaq 0x3238(%rip), %rsi      # 0x659e
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1120
movq 0x18(%r14), %rax
movq (%rax), %rdx
leaq 0x322e(%rip), %rsi      # 0x65ac
jmp 0x339b
movq 0x8(%r14), %rax
movq (%rax), %rdx
leaq 0x322b(%rip), %rsi      # 0x65b9
jmp 0x339b
movq 0x8(%r14), %rdx
leaq 0x31ed(%rip), %rsi      # 0x6588
movq %rbx, %rdi
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x1120
movl 0x18(%r14), %edx
leaq 0x359a(%rip), %rsi      # 0x6955
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1120
jmp 0x3412
cmpl $0x0, 0x18(%r14)
je 0x33e3
leaq 0x316b(%rip), %rdi      # 0x6540
pushq $0x2
popq %rsi
pushq $0x1
popq %rdx
movq %rbx, %rcx
callq 0x11c0
movq 0x20(%r14), %rdx
leaq 0x3165(%rip), %rsi      # 0x6553
jmp 0x3408
movq 0x18(%r14), %rdx
leaq 0x3148(%rip), %rsi      # 0x6543
jmp 0x3408
movq 0x18(%r14), %rdx
leaq 0x3061(%rip), %rsi      # 0x6469
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1120
pushq $0xa
popq %rdi
movq %rbx, %rsi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x10f0
movq 0x18(%r14), %rdi
callq 0x17f0
movq %rax, %r15
movq 0x20(%r14), %rcx
movq 0x28(%r14), %r8
leaq 0x3105(%rip), %rsi      # 0x6548
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x1120
movq %r15, %rdi
callq 0x1040
jmp 0x3412
movq 0x18(%r14), %rdx
leaq 0x30f2(%rip), %rsi      # 0x6557
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1120
movq 0x20(%r14), %r14
leaq 0x30d6(%rip), %r15      # 0x6550
xorl %r12d, %r12d
movq %r14, %rdi
callq 0x29db
cmpq %rax, %r12
jae 0x3412
movq %r14, %rdi
movq %r12, %rsi
callq 0x29c6
movq (%rax), %rdx
movq %rbx, %rdi
movq %r15, %rsi
xorl %eax, %eax
callq 0x1120
incq %r12
jmp 0x347d
leaq 0x338d(%rip), %rdi      # 0x683e
leaq 0x3018(%rip), %rsi      # 0x64d0
leaq 0x30a3(%rip), %rcx      # 0x6562
movl $0x2a2, %edx            # imm = 0x2A2
callq 0x10d0
leaq 0x336e(%rip), %rdi      # 0x683e
leaq 0x2ff9(%rip), %rsi      # 0x64d0
leaq 0x3084(%rip), %rcx      # 0x6562
movl $0x28d, %edx            # imm = 0x28D
callq 0x10d0