// File: /workspace/github_c_makefile_star2_O0/Ihsoh[P]ilang/compiler/frontend/irgen.c
// Function: ir_func
static void _ir_func(
	IRGeneratorContext *ctx,
	ParserASTNode *node
) {
	assert(ctx);
	assert(node);
	assert(node->type == FE_NODE_FUNC);

	ctx->func_symbol = FE_FUNC_AST_NODE_GET_SYMBOL(node);
	assert(ctx->func_symbol);

	ParserASTNode *node_identifier = NULL;
	ParserASTNode *node_func_params = NULL;
	ParserASTNode *node_return_type = NULL;
	ParserASTNode *node_body = NULL;

	int nchilds = node->nchilds;
	if (nchilds == 3) {
		node_identifier = node->childs[0];
		node_func_params = node->childs[1];
		node_body = node->childs[2];
	} else if (nchilds == 4) {
		node_identifier = node->childs[0];
		node_func_params = node->childs[1];
		node_return_type = node->childs[2];
		node_body = node->childs[3];
	} else {
		assert(0);
	}
	assert(node_identifier->type == FE_NODE_IDENTIFIER);
	assert(node_func_params->type == FE_NODE_FUNC_PARAMS);
	if (node_func_params->nchilds > 0) {
		assert(node_func_params->childs[0]->type == FE_NODE_FUNC_PARAMS_ITEM);
	}

	rstr_append_with_char(ctx->body, '\n');

	rstr_append_with_cstr(ctx->body, "function");

	rstr_append_with_char(ctx->body, ' ');

	ResizableString rstr_id;
	rstr_init(&rstr_id);
	_ir_identifier_name(ctx, &rstr_id, node_identifier);
	rstr_append_with_rstr(ctx->body, &rstr_id);
	rstr_free(&rstr_id);

	rstr_append_with_cstr(ctx->body, "(");
	_ir_func_type_params(ctx, ctx->body, node_func_params);
	rstr_append_with_cstr(ctx->body, ")");

	if (node_return_type != NULL) {
		rstr_append_with_char(ctx->body, ':');
		ResizableString rstr_return_type;
		rstr_init(&rstr_return_type);
		_ir_type(ctx, &rstr_return_type, node_return_type);
		rstr_append_with_rstr(ctx->body, &rstr_return_type);
		rstr_free(&rstr_return_type);
	}

	rstr_append_with_char(ctx->body, ' ');

	if (node_body->type == FE_NODE_STATS_BLOCK) {
		rstr_append_with_cstr(ctx->body, " {\n");

		for (int i = 0; i < node_func_params->nchilds; i++) {
			ParserASTNode *node_param = node_func_params->childs[i];
			if (node_param->type == FE_NODE_FUNC_PARAMS_ELLIPSIS_ITEM) {
				continue;
			}

			ParserSymbol *symbol = FE_FUNC_PARAM_AST_NODE_GET_SYMBOL(node_param);

			assert(!FE_VAR_SYMBOL_GET_HAS_CODE_GEN_NAME(symbol));

			FE_VAR_SYMBOL_SET_HAS_CODE_GEN_NAME(symbol, true);	
			ResizableString *code_gen_name = FE_VAR_SYMBOL_GET_CODE_GEN_NAME(symbol);
			rstr_init(code_gen_name);
			_ir_identifier_name_tk(ctx, code_gen_name, symbol->token);
		}

		ResizableString *body = ctx->body;
		ctx->body = rstr_new();
		ctx->local_var_defs = rstr_new();

		_ir_stats_block(ctx, node_body);

		rstr_append_with_rstr(body, ctx->local_var_defs);
		rstr_append_with_rstr(body, ctx->body);
	
		rstr_free(ctx->body);
		ctx->body = body;
		rstr_free(ctx->local_var_defs);
		ctx->local_var_defs = NULL;

		rstr_append_with_cstr(ctx->body, "}");
	} else if (node_body->type == FE_NODE_DUMMY) {
		rstr_append_with_cstr(ctx->body, "dummy");
	} else {
		assert(0);
	}

	rstr_append_with_cstr(ctx->body, "\n\n");
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpq $0x0, -0x8(%rbp)
je 0x106dc
jmp 0x106fb
leaq 0x6be73(%rip), %rdi     # 0x7c556
leaq 0x63caa(%rip), %rsi     # 0x74394
movl $0x12c1, %edx           # imm = 0x12C1
leaq 0x65a28(%rip), %rcx     # 0x7611e
callq 0x30a0
cmpq $0x0, -0x10(%rbp)
je 0x10704
jmp 0x10723
leaq 0x658c8(%rip), %rdi     # 0x75fd3
leaq 0x63c82(%rip), %rsi     # 0x74394
movl $0x12c2, %edx           # imm = 0x12C2
leaq 0x65a00(%rip), %rcx     # 0x7611e
callq 0x30a0
movq -0x10(%rbp), %rax
cmpl $0xa00, (%rax)          # imm = 0xA00
jne 0x10731
jmp 0x10750
leaq 0x65a1b(%rip), %rdi     # 0x76153
leaq 0x63c55(%rip), %rsi     # 0x74394
movl $0x12c3, %edx           # imm = 0x12C3
leaq 0x659d3(%rip), %rcx     # 0x7611e
callq 0x30a0
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x8(%rbp), %rax
cmpq $0x0, 0x40(%rax)
je 0x1076d
jmp 0x1078c
leaq 0x659fa(%rip), %rdi     # 0x7616e
leaq 0x63c19(%rip), %rsi     # 0x74394
movl $0x12c6, %edx           # imm = 0x12C6
leaq 0x65997(%rip), %rcx     # 0x7611e
callq 0x30a0
movq $0x0, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
movq $0x0, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x10(%rbp), %rax
movl 0x44(%rax), %eax
movl %eax, -0x34(%rbp)
cmpl $0x3, -0x34(%rbp)
jne 0x107ed
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movq 0x10(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x10855
cmpl $0x4, -0x34(%rbp)
jne 0x10834
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movq 0x18(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x10853
leaq 0x61c20(%rip), %rdi     # 0x7245b
leaq 0x63b52(%rip), %rsi     # 0x74394
movl $0x12d8, %edx           # imm = 0x12D8
leaq 0x658d0(%rip), %rcx     # 0x7611e
callq 0x30a0
jmp 0x10855
movq -0x18(%rbp), %rax
cmpl $0x200, (%rax)          # imm = 0x200
jne 0x10863
jmp 0x10882
leaq 0x63dc0(%rip), %rdi     # 0x7462a
leaq 0x63b23(%rip), %rsi     # 0x74394
movl $0x12da, %edx           # imm = 0x12DA
leaq 0x658a1(%rip), %rcx     # 0x7611e
callq 0x30a0
movq -0x20(%rbp), %rax
cmpl $0xa01, (%rax)          # imm = 0xA01
jne 0x10890
jmp 0x108af
leaq 0x658e8(%rip), %rdi     # 0x7617f
leaq 0x63af6(%rip), %rsi     # 0x74394
movl $0x12db, %edx           # imm = 0x12DB
leaq 0x65874(%rip), %rcx     # 0x7611e
callq 0x30a0
movq -0x20(%rbp), %rax
cmpl $0x0, 0x44(%rax)
jle 0x108ef
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rax
movq (%rax), %rax
cmpl $0xa02, (%rax)          # imm = 0xA02
jne 0x108ce
jmp 0x108ed
leaq 0x658d8(%rip), %rdi     # 0x761ad
leaq 0x63ab8(%rip), %rsi     # 0x74394
movl $0x12dd, %edx           # imm = 0x12DD
leaq 0x65836(%rip), %rcx     # 0x7611e
callq 0x30a0
jmp 0x108ef
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
movl $0xa, %esi
callq 0x8ea0
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
leaq 0x63f79(%rip), %rsi     # 0x74889
callq 0x8d70
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
movl $0x20, %esi
callq 0x8ea0
leaq -0x48(%rbp), %rdi
callq 0x8c90
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rdx
leaq -0x48(%rbp), %rsi
callq 0x10be0
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
leaq -0x48(%rbp), %rsi
callq 0x9100
leaq -0x48(%rbp), %rdi
callq 0x9310
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
leaq 0x670f3(%rip), %rsi     # 0x77a5d
callq 0x8d70
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rsi
movq -0x20(%rbp), %rdx
callq 0x13110
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
leaq 0x6660b(%rip), %rsi     # 0x76f9e
callq 0x8d70
cmpq $0x0, -0x28(%rbp)
je 0x109e5
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
movl $0x3a, %esi
callq 0x8ea0
leaq -0x58(%rbp), %rdi
callq 0x8c90
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rdx
leaq -0x58(%rbp), %rsi
callq 0x10ca0
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
leaq -0x58(%rbp), %rsi
callq 0x9100
leaq -0x58(%rbp), %rdi
callq 0x9310
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
movl $0x20, %esi
callq 0x8ea0
movq -0x30(%rbp), %rax
cmpl $0xb00, (%rax)          # imm = 0xB00
jne 0x10b72
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
leaq 0x656e2(%rip), %rsi     # 0x760f8
callq 0x8d70
movl $0x0, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
movq -0x20(%rbp), %rcx
cmpl 0x44(%rcx), %eax
jge 0x10acf
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rax
movslq -0x5c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
cmpl $0xa03, (%rax)          # imm = 0xA03
jne 0x10a54
jmp 0x10ac1
movq -0x68(%rbp), %rax
movq 0x60(%rax), %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
testb $0x1, 0x48(%rax)
jne 0x10a6c
jmp 0x10a8b
leaq 0x65778(%rip), %rdi     # 0x761eb
leaq 0x6391a(%rip), %rsi     # 0x74394
movl $0x1306, %edx           # imm = 0x1306
leaq 0x65698(%rip), %rcx     # 0x7611e
callq 0x30a0
movq -0x70(%rbp), %rax
movb $0x1, 0x48(%rax)
movq -0x70(%rbp), %rax
addq $0x30, %rax
addq $0x20, %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdi
callq 0x8c90
movq -0x8(%rbp), %rdi
movq -0x78(%rbp), %rsi
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rdx
callq 0x13490
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x10a22
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x80(%rbp)
callq 0x91e0
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x20(%rax)
callq 0x91e0
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x1d950
movq -0x80(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rsi
callq 0x9100
movq -0x80(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rsi
callq 0x9100
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x9310
movq -0x80(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rdi
callq 0x9310
movq -0x8(%rbp), %rax
movq $0x0, 0x30(%rax)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
leaq 0x656ad(%rip), %rsi     # 0x76218
callq 0x8d70
jmp 0x10bb5
movq -0x30(%rbp), %rax
cmpl $0x900, (%rax)          # imm = 0x900
jne 0x10b94
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
leaq 0x6568d(%rip), %rsi     # 0x7621a
callq 0x8d70
jmp 0x10bb3
leaq 0x618c0(%rip), %rdi     # 0x7245b
leaq 0x637f2(%rip), %rsi     # 0x74394
movl $0x1320, %edx           # imm = 0x1320
leaq 0x65570(%rip), %rcx     # 0x7611e
callq 0x30a0
jmp 0x10bb5
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
leaq 0x65531(%rip), %rsi     # 0x760f5
callq 0x8d70
addq $0x80, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)