// File: /workspace/github_c_makefile_star2_O0/yutopp[P]cc/ir.c
// Function: build_statement
void build_statement(IRBuilder* builder, Node* node, IRFunction* f) {
    switch(node->kind) {
    case NODE_STMT_COMPOUND:
    {
        printf("LOG: statement compound\n");

        Vector* stmts = node->value.stmt_compound.stmts;
        for(size_t i=0; i<vector_len(stmts); ++i) {
            Node** n = (Node**)vector_at(stmts, i);
            build_statement(builder, *n, f);
        }
        break;
    }

    case NODE_STMT_EXPR:
        printf("LOG: statement expr\n");

        if (node->value.stmt_expr.expr) {
            build_expression(builder, node->value.stmt_expr.expr, f);
        }
        break;

    case NODE_STMT_IF:
        fprintf(DEBUGOUT, "LOG: statement if\n");

        IRSymbolID cond = build_expression(builder, node->value.stmt_if.cond, f);

        IRBB* then_bb = ir_builder_build_bb(builder);
        IRBB* else_bb = NULL;
        if (node->value.stmt_if.else_b) {
            else_bb = ir_builder_build_bb(builder);
        }
        IRBB* final_bb = ir_builder_build_bb(builder);

        // Terminate current bb
        IRInst inst = {
            .kind = IR_INST_KIND_BRANCH,
            .value = {
                .branch = {
                    .cond = cond,
                    .then_bb = then_bb,
                    .else_bb = else_bb != NULL ? else_bb : final_bb,
                },
            },
        };
        ir_bb_terminate(builder->current_bb, inst);

        // then block
        ir_builder_set_current_bb(builder, then_bb);
        build_statement(builder, node->value.stmt_if.then_b, f);
        if (builder->current_bb->term == NULL) {
            IRInst then_inst = {
                .kind = IR_INST_KIND_JUMP,
                .value = {
                    .jump = {
                        .next_bb = final_bb,
                    },
                },
            };
            ir_bb_terminate(builder->current_bb, then_inst);
        }

        // then block
        if (node->value.stmt_if.else_b) {
            ir_builder_set_current_bb(builder, else_bb);
            build_statement(builder, node->value.stmt_if.else_b, f);
            if (builder->current_bb->term == NULL) {
                IRInst else_inst = {
                    .kind = IR_INST_KIND_JUMP,
                    .value = {
                        .jump = {
                            .next_bb = final_bb,
                        },
                    },
                };
                ir_bb_terminate(builder->current_bb, else_inst);
            }
        }

        ir_builder_set_current_bb(builder, final_bb);

        break;

    case NODE_STMT_JUMP:
        printf("LOG: statement jump\n");

        switch(node->value.stmt_jump.kind) {
        case TOK_KIND_RETURN:
        {
            IRSymbolID expr_ref = build_expression(builder, node->value.stmt_jump.expr, f);

            IRInst inst = {
                .kind = IR_INST_KIND_RET,
                .value = {
                    .ret = {
                        .id = expr_ref,
                    },
                },
            };
            ir_bb_terminate(builder->current_bb, inst);

            break;
        }

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

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

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x170, %rsp            # imm = 0x170
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %eax
addl $-0x2, %eax
movl %eax, %ecx
movq %rcx, -0x120(%rbp)
subl $0x3, %eax
ja 0x5d90
movq -0x120(%rbp), %rax
leaq 0x5bcc(%rip), %rcx      # 0xb5cc
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x5d7e(%rip), %rdi      # 0xb78e
movb $0x0, %al
callq 0x1090
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
movq $0x0, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x128(%rbp)
movq -0x20(%rbp), %rdi
callq 0x4580
movq %rax, %rcx
movq -0x128(%rbp), %rax
cmpq %rcx, %rax
jae 0x5a81
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x4530
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rax
movq (%rax), %rsi
movq -0x18(%rbp), %rdx
callq 0x59c0
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x5a2b
jmp 0x5daf
leaq 0x5d1a(%rip), %rdi      # 0xb7a7
movb $0x0, %al
callq 0x1090
movq -0x10(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x5ab4
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x18(%rbp), %rdx
callq 0x5e70
jmp 0x5daf
movq 0x9518(%rip), %rax      # 0xefd8
movq (%rax), %rdi
leaq 0x5cf2(%rip), %rsi      # 0xb7bc
movb $0x0, %al
callq 0x10e0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x18(%rbp), %rdx
callq 0x5e70
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rdi
callq 0x65b0
movq %rax, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0x5b17
movq -0x8(%rbp), %rdi
callq 0x65b0
movq %rax, -0x48(%rbp)
movq -0x8(%rbp), %rdi
callq 0x65b0
movq %rax, -0x50(%rbp)
movl $0x2, -0x80(%rbp)
leaq -0x80(%rbp), %rax
addq $0x8, %rax
movq -0x38(%rbp), %rcx
movq %rcx, -0x78(%rbp)
movq -0x40(%rbp), %rcx
movq %rcx, -0x70(%rbp)
addq $0x10, %rax
movq %rax, -0x130(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0x5b62
movq -0x48(%rbp), %rax
movq %rax, -0x138(%rbp)
jmp 0x5b6d
movq -0x50(%rbp), %rax
movq %rax, -0x138(%rbp)
movq -0x130(%rbp), %rax
movq -0x138(%rbp), %rcx
movq %rcx, (%rax)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movups -0x80(%rbp), %xmm0
movups -0x70(%rbp), %xmm1
movups -0x60(%rbp), %xmm2
movq %rsp, %rax
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0x6610
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x6690
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rsi
movq -0x18(%rbp), %rdx
callq 0x59c0
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
cmpq $0x0, 0x18(%rax)
jne 0x5c2e
leaq -0xb0(%rbp), %rdi
xorl %esi, %esi
movl $0x30, %edx
callq 0x10c0
movl $0x3, -0xb0(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movups -0xb0(%rbp), %xmm0
movups -0xa0(%rbp), %xmm1
movups -0x90(%rbp), %xmm2
movq %rsp, %rax
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0x6610
movq -0x10(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0x5cc8
movq -0x8(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x6690
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x18(%rbp), %rdx
callq 0x59c0
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
cmpq $0x0, 0x18(%rax)
jne 0x5cc6
leaq -0xe0(%rbp), %rdi
xorl %esi, %esi
movl $0x30, %edx
callq 0x10c0
movl $0x3, -0xe0(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movups -0xe0(%rbp), %xmm0
movups -0xd0(%rbp), %xmm1
movups -0xc0(%rbp), %xmm2
movq %rsp, %rax
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0x6610
jmp 0x5cc8
movq -0x8(%rbp), %rdi
movq -0x50(%rbp), %rsi
callq 0x6690
jmp 0x5daf
leaq 0x5aee(%rip), %rdi      # 0xb7cf
xorl %eax, %eax
callq 0x1090
movq -0x10(%rbp), %rax
movl 0x8(%rax), %eax
subl $0x19, %eax
jne 0x5d6f
jmp 0x5cf6
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rsi
movq -0x18(%rbp), %rdx
callq 0x5e70
movq %rax, -0xe8(%rbp)
leaq -0x118(%rbp), %rdi
xorl %esi, %esi
movl $0x30, %edx
callq 0x10c0
movl $0x1, -0x118(%rbp)
movq -0xe8(%rbp), %rax
movq %rax, -0x110(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movups -0x118(%rbp), %xmm0
movups -0x108(%rbp), %xmm1
movups -0xf8(%rbp), %xmm2
movq %rsp, %rax
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0x6610
jmp 0x5d8e
leaq 0x5bf0(%rip), %rdi      # 0xb966
leaq 0x5873(%rip), %rsi      # 0xb5f0
movl $0x13f, %edx            # imm = 0x13F
leaq 0x5a5b(%rip), %rcx      # 0xb7e4
callq 0x10b0
jmp 0x5daf
leaq 0x5bcf(%rip), %rdi      # 0xb966
leaq 0x5852(%rip), %rsi      # 0xb5f0
movl $0x145, %edx            # imm = 0x145
leaq 0x5a3a(%rip), %rcx      # 0xb7e4
callq 0x10b0
addq $0x170, %rsp            # imm = 0x170
popq %rbp
retq
nopl (%rax,%rax)