// File: /workspace/github_c_makefile_star2_O0/Ihsoh[P]ilang/compiler/frontend/irgen_llvmir.c
// Function: ir_var
static void _ir_var(
	IRGeneratorLlvmirContext *ctx,
	ParserASTNode *node
) {
	assert(ctx);
	assert(node);
	assert(node->type == FE_NODE_VAR);
	assert(node->nchilds > 0);

	int align = FE_VAR_AST_NODE_GET_ALIGN(node);

	for (int i = 0; i < node->nchilds; i++) {
		ParserASTNode *node_var_item = node->childs[i];
		assert(node_var_item->type == FE_NODE_VAR_ITEM);
		assert(node_var_item->nchilds == 2 || node_var_item->nchilds == 3);

		ParserASTNode *node_identifier = node_var_item->childs[0];
		assert(node_identifier->type == FE_NODE_IDENTIFIER);
		ParserASTNode *node_type = node_var_item->childs[1];
		ParserASTNode *node_expr = NULL;

		if (node_var_item->nchilds == 3) {
			node_expr = node_var_item->childs[2];
		}

		switch (FE_VAR_AST_NODE_GET_TYPE(node)) {
			case FE_VAR_TYPE_GLOBAL: {
				// @c = common global i8 zeroinitializer, align 1
				ResizableString rstr;
				rstr_init(&rstr);

				rstr_append_with_cstr(&rstr, "@");
				rstr_append_with_raw(&rstr, node_identifier->token->content, node_identifier->token->len);
				
				if (node_expr == NULL) {
					rstr_append_with_cstr(&rstr, " = common global ");
				} else {
					rstr_append_with_cstr(&rstr, " = global ");
				}

				ResizableString rstr_type;
				rstr_init(&rstr_type);
				_ir_type(ctx, &rstr_type, node_type);
				rstr_append_with_cstr(&rstr, RSTR_CSTR(&rstr_type));
				rstr_free(&rstr_type);

				rstr_append_with_cstr(&rstr, " ");

				if (node_expr == NULL) {
					_ir_zero_initializer(ctx, &rstr, node_type);
				} else {
					_ir_constexpr_initializer(ctx, &rstr, node_expr);
				}

				if (align > 0) {
					rstr_appendf(&rstr, ", align %d", align);
				}

				rstr_append_with_cstr(ctx->body, RSTR_CSTR(&rstr));

				rstr_free(&rstr);

				// 更新全局变量符号在代码生成时的名字。
				ParserSymbol *symbol = FE_VAR_ITEM_AST_NODE_GET_SYMBOL(node_var_item);
				FE_VAR_SYMBOL_SET_HAS_CODE_GEN_NAME(symbol, true);
				rstr_init(FE_VAR_SYMBOL_GET_CODE_GEN_NAME(symbol));
				rstr_append_with_char(FE_VAR_SYMBOL_GET_CODE_GEN_NAME(symbol), '@');
				rstr_append_with_raw(
					FE_VAR_SYMBOL_GET_CODE_GEN_NAME(symbol),
					node_identifier->token->content,
					node_identifier->token->len
				);

				rstr_append_with_cstr(ctx->body, "\n");
				break;
			}
			case FE_VAR_TYPE_LOCAL: {
				// %3 = alloca i32, align 4
				ResizableString rstr;
				rstr_init(&rstr);

				size_t no = FE_FUNC_SYMBOL_NEXT_NO(ctx->func_symbol);
				ResizableString rstr_local_name;
				rstr_init_with_raw(
					&rstr_local_name,
					node_identifier->token->content,
					node_identifier->token->len
				);
				rstr_appendf(
					&rstr_local_name,
					"_%zu",
					no
				);

				rstr_append_with_cstr(&rstr, "%");
				rstr_append_with_rstr(&rstr, &rstr_local_name);
				rstr_append_with_cstr(&rstr, " = alloca ");

				ResizableString rstr_type;
				rstr_init(&rstr_type);
				_ir_type(ctx, &rstr_type, node_type);
				rstr_append_with_cstr(&rstr, RSTR_CSTR(&rstr_type));

				if (align > 0) {
					rstr_appendf(&rstr, ", align %d", align);
				}

				rstr_append_with_cstr(&rstr, "\n");

				if (node_expr != NULL) {
					ResizableString rstr_expr;
					rstr_init(&rstr_expr);

					_ExprResult result;
					_expr_result_init(&result);

					_ExprResult casted_result;
					_expr_result_init(&casted_result);

					_ir_expr_wrapper_val(ctx, &rstr_expr, &result, node_expr);
					_expr_result_cast(
						ctx,
						&casted_result,
						node_type,
						&result,
						FE_EXPR_AST_NODE_GET_TYPE_NODE(node_expr)
					);
					rstr_append_with_rstr(&rstr_expr, &(casted_result.rstr_for_result_ptr));
					rstr_append_with_rstr(&rstr_expr, &(casted_result.rstr_for_result));
					rstr_appendf(
						&rstr_expr,
						"store %s, %s* %%",
						RSTR_CSTR(&(casted_result.rstr_result)),
						RSTR_CSTR(&rstr_type)
					);
					rstr_append_with_rstr(
						&rstr_expr,
						&rstr_local_name	
					);
					rstr_append_with_cstr(&rstr_expr, "\n");

					rstr_append_with_rstr(ctx->body, &rstr_expr);

					rstr_init(&rstr_expr);
					_expr_result_free(&result);
					_expr_result_free(&casted_result);
				}

				assert(ctx->local_var_defs);
				rstr_append_with_cstr(ctx->local_var_defs, RSTR_CSTR(&rstr));

				// 更新局部变量符号在代码生成时的名字。
				ParserSymbol *symbol = FE_VAR_ITEM_AST_NODE_GET_SYMBOL(node_var_item);
				FE_VAR_SYMBOL_SET_HAS_CODE_GEN_NAME(symbol, true);
				rstr_init(FE_VAR_SYMBOL_GET_CODE_GEN_NAME(symbol));
				rstr_append_with_char(FE_VAR_SYMBOL_GET_CODE_GEN_NAME(symbol), '%');
				rstr_append_with_rstr(
					FE_VAR_SYMBOL_GET_CODE_GEN_NAME(symbol),
					&rstr_local_name
				);

				rstr_free(&rstr_type);
				rstr_free(&rstr);
				rstr_free(&rstr_local_name);
				break;
			}
			case FE_VAR_TYPE_STRUCT_MEMBER: {
				assert(0);
				break;
			}
			default: {
				assert(0);
			}
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x200, %rsp            # imm = 0x200
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpq $0x0, -0x8(%rbp)
je 0x285cc
jmp 0x285eb
leaq 0x53f83(%rip), %rdi     # 0x7c556
leaq 0x4faf6(%rip), %rsi     # 0x780d0
movl $0x3f8, %edx            # imm = 0x3F8
leaq 0x4fd08(%rip), %rcx     # 0x782ee
callq 0x30a0
cmpq $0x0, -0x10(%rbp)
je 0x285f4
jmp 0x28613
leaq 0x4d9d8(%rip), %rdi     # 0x75fd3
leaq 0x4face(%rip), %rsi     # 0x780d0
movl $0x3f9, %edx            # imm = 0x3F9
leaq 0x4fce0(%rip), %rcx     # 0x782ee
callq 0x30a0
movq -0x10(%rbp), %rax
cmpl $0xc00, (%rax)          # imm = 0xC00
jne 0x28621
jmp 0x28640
leaq 0x561ae(%rip), %rdi     # 0x7e7d6
leaq 0x4faa1(%rip), %rsi     # 0x780d0
movl $0x3fa, %edx            # imm = 0x3FA
leaq 0x4fcb3(%rip), %rcx     # 0x782ee
callq 0x30a0
movq -0x10(%rbp), %rax
cmpl $0x0, 0x44(%rax)
jle 0x2864c
jmp 0x2866b
leaq 0x4bf62(%rip), %rdi     # 0x745b5
leaq 0x4fa76(%rip), %rsi     # 0x780d0
movl $0x3fb, %edx            # imm = 0x3FB
leaq 0x4fc88(%rip), %rcx     # 0x782ee
callq 0x30a0
movq -0x10(%rbp), %rax
movl 0x70(%rax), %eax
movl %eax, -0x14(%rbp)
movl $0x0, -0x18(%rbp)
movl -0x18(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x44(%rcx), %eax
jge 0x28d4a
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movslq -0x18(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpl $0xc01, (%rax)          # imm = 0xC01
jne 0x286ae
jmp 0x286cd
leaq 0x4bf12(%rip), %rdi     # 0x745c7
leaq 0x4fa14(%rip), %rsi     # 0x780d0
movl $0x401, %edx            # imm = 0x401
leaq 0x4fc26(%rip), %rcx     # 0x782ee
callq 0x30a0
movq -0x20(%rbp), %rax
cmpl $0x2, 0x44(%rax)
je 0x286e1
movq -0x20(%rbp), %rax
cmpl $0x3, 0x44(%rax)
jne 0x286e3
jmp 0x28702
leaq 0x4bf05(%rip), %rdi     # 0x745ef
leaq 0x4f9df(%rip), %rsi     # 0x780d0
movl $0x402, %edx            # imm = 0x402
leaq 0x4fbf1(%rip), %rcx     # 0x782ee
callq 0x30a0
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rax
movq (%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpl $0x200, (%rax)          # imm = 0x200
jne 0x2871f
jmp 0x2873e
leaq 0x4bf04(%rip), %rdi     # 0x7462a
leaq 0x4f9a3(%rip), %rsi     # 0x780d0
movl $0x405, %edx            # imm = 0x405
leaq 0x4fbb5(%rip), %rcx     # 0x782ee
callq 0x30a0
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x3, 0x44(%rax)
jne 0x28770
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rax
movq 0x10(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rax
movzbl 0x60(%rax), %eax
movl %eax, -0x1b4(%rbp)
subl $0x1, %eax
je 0x287aa
jmp 0x28785
movl -0x1b4(%rbp), %eax
subl $0x2, %eax
je 0x28980
jmp 0x28796
movl -0x1b4(%rbp), %eax
subl $0x3, %eax
je 0x28cfc
jmp 0x28d1b
leaq -0x48(%rbp), %rdi
callq 0x8c90
leaq -0x48(%rbp), %rdi
leaq 0x4fb6a(%rip), %rsi     # 0x78328
callq 0x8d70
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rsi
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movl 0x4(%rax), %edx
leaq -0x48(%rbp), %rdi
callq 0x8f90
cmpq $0x0, -0x38(%rbp)
jne 0x287fc
leaq -0x48(%rbp), %rdi
leaq 0x4fb35(%rip), %rsi     # 0x7832a
callq 0x8d70
jmp 0x2880c
leaq -0x48(%rbp), %rdi
leaq 0x4fb35(%rip), %rsi     # 0x7833c
callq 0x8d70
leaq -0x58(%rbp), %rdi
callq 0x8c90
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rdx
leaq -0x58(%rbp), %rsi
callq 0x299e0
cmpq $0x0, -0x50(%rbp)
jne 0x2883d
leaq 0x4f081(%rip), %rax     # 0x778b5
movq %rax, -0x1c0(%rbp)
jmp 0x28848
movq -0x50(%rbp), %rax
movq %rax, -0x1c0(%rbp)
movq -0x1c0(%rbp), %rsi
leaq -0x48(%rbp), %rdi
callq 0x8d70
leaq -0x58(%rbp), %rdi
callq 0x9310
leaq -0x48(%rbp), %rdi
leaq 0x4abe8(%rip), %rsi     # 0x73454
callq 0x8d70
cmpq $0x0, -0x38(%rbp)
jne 0x2888b
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rdx
leaq -0x48(%rbp), %rsi
callq 0x2a050
jmp 0x2889c
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rdx
leaq -0x48(%rbp), %rsi
callq 0x2a180
cmpl $0x0, -0x14(%rbp)
jle 0x288b7
movl -0x14(%rbp), %edx
leaq -0x48(%rbp), %rdi
leaq 0x4fa97(%rip), %rsi     # 0x78347
movb $0x0, %al
callq 0x94d0
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x1c8(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0x288dd
leaq 0x4efe1(%rip), %rax     # 0x778b5
movq %rax, -0x1d0(%rbp)
jmp 0x288e8
movq -0x40(%rbp), %rax
movq %rax, -0x1d0(%rbp)
movq -0x1c8(%rbp), %rdi
movq -0x1d0(%rbp), %rsi
callq 0x8d70
leaq -0x48(%rbp), %rdi
callq 0x9310
movq -0x20(%rbp), %rax
movq 0x60(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movb $0x1, 0x48(%rax)
movq -0x60(%rbp), %rdi
addq $0x30, %rdi
addq $0x20, %rdi
callq 0x8c90
movq -0x60(%rbp), %rdi
addq $0x30, %rdi
addq $0x20, %rdi
movl $0x40, %esi
callq 0x8ea0
movq -0x60(%rbp), %rdi
addq $0x30, %rdi
addq $0x20, %rdi
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rsi
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movl 0x4(%rax), %edx
callq 0x8f90
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
leaq 0x4d780(%rip), %rsi     # 0x760f6
callq 0x8d70
jmp 0x28d3a
leaq -0x70(%rbp), %rdi
callq 0x8c90
movq -0x8(%rbp), %rax
movq 0x40(%rax), %rcx
movl 0x54(%rcx), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, 0x54(%rcx)
movl %eax, %eax
movq %rax, -0x78(%rbp)
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rsi
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movl 0x4(%rax), %edx
leaq -0x88(%rbp), %rdi
callq 0x8ee0
movq -0x78(%rbp), %rdx
leaq -0x88(%rbp), %rdi
leaq 0x4f97b(%rip), %rsi     # 0x78352
movb $0x0, %al
callq 0x94d0
leaq -0x70(%rbp), %rdi
leaq 0x4f988(%rip), %rsi     # 0x78371
callq 0x8d70
leaq -0x70(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x9100
leaq -0x70(%rbp), %rdi
leaq 0x4f94e(%rip), %rsi     # 0x78357
callq 0x8d70
leaq -0x98(%rbp), %rdi
callq 0x8c90
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rdx
leaq -0x98(%rbp), %rsi
callq 0x299e0
cmpq $0x0, -0x90(%rbp)
jne 0x28a48
leaq 0x4ee76(%rip), %rax     # 0x778b5
movq %rax, -0x1d8(%rbp)
jmp 0x28a56
movq -0x90(%rbp), %rax
movq %rax, -0x1d8(%rbp)
movq -0x1d8(%rbp), %rsi
leaq -0x70(%rbp), %rdi
callq 0x8d70
cmpl $0x0, -0x14(%rbp)
jle 0x28a81
movl -0x14(%rbp), %edx
leaq -0x70(%rbp), %rdi
leaq 0x4f8cd(%rip), %rsi     # 0x78347
movb $0x0, %al
callq 0x94d0
leaq -0x70(%rbp), %rdi
leaq 0x4d66a(%rip), %rsi     # 0x760f6
callq 0x8d70
cmpq $0x0, -0x38(%rbp)
je 0x28c07
leaq -0xa8(%rbp), %rdi
callq 0x8c90
leaq -0x128(%rbp), %rdi
callq 0x2a260
leaq -0x1a8(%rbp), %rdi
callq 0x2a260
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rcx
leaq -0xa8(%rbp), %rsi
leaq -0x128(%rbp), %rdx
callq 0x2a300
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rdx
movq -0x38(%rbp), %rax
movq 0x68(%rax), %r8
leaq -0x1a8(%rbp), %rsi
leaq -0x128(%rbp), %rcx
callq 0x2a360
leaq -0x1a8(%rbp), %rsi
addq $0x10, %rsi
leaq -0xa8(%rbp), %rdi
callq 0x9100
leaq -0x1a8(%rbp), %rsi
leaq -0xa8(%rbp), %rdi
callq 0x9100
cmpq $0x0, -0x180(%rbp)
jne 0x28b42
leaq 0x4ed7c(%rip), %rax     # 0x778b5
movq %rax, -0x1e0(%rbp)
jmp 0x28b50
movq -0x180(%rbp), %rax
movq %rax, -0x1e0(%rbp)
movq -0x1e0(%rbp), %rax
movq %rax, -0x1e8(%rbp)
cmpq $0x0, -0x90(%rbp)
jne 0x28b78
leaq 0x4ed46(%rip), %rax     # 0x778b5
movq %rax, -0x1f0(%rbp)
jmp 0x28b86
movq -0x90(%rbp), %rax
movq %rax, -0x1f0(%rbp)
movq -0x1e8(%rbp), %rdx
movq -0x1f0(%rbp), %rcx
leaq -0xa8(%rbp), %rdi
leaq 0x4f7c0(%rip), %rsi     # 0x78362
movb $0x0, %al
callq 0x94d0
leaq -0xa8(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x9100
leaq -0xa8(%rbp), %rdi
leaq 0x4d52c(%rip), %rsi     # 0x760f6
callq 0x8d70
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x9100
leaq -0xa8(%rbp), %rdi
callq 0x8c90
leaq -0x128(%rbp), %rdi
callq 0x2c6a0
leaq -0x1a8(%rbp), %rdi
callq 0x2c6a0
movq -0x8(%rbp), %rax
cmpq $0x0, 0x30(%rax)
je 0x28c14
jmp 0x28c33
leaq 0x4f758(%rip), %rdi     # 0x78373
leaq 0x4f4ae(%rip), %rsi     # 0x780d0
movl $0x488, %edx            # imm = 0x488
leaq 0x4f6c0(%rip), %rcx     # 0x782ee
callq 0x30a0
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x1f8(%rbp)
cmpq $0x0, -0x68(%rbp)
jne 0x28c59
leaq 0x4ec65(%rip), %rax     # 0x778b5
movq %rax, -0x200(%rbp)
jmp 0x28c64
movq -0x68(%rbp), %rax
movq %rax, -0x200(%rbp)
movq -0x1f8(%rbp), %rdi
movq -0x200(%rbp), %rsi
callq 0x8d70
movq -0x20(%rbp), %rax
movq 0x60(%rax), %rax
movq %rax, -0x1b0(%rbp)
movq -0x1b0(%rbp), %rax
movb $0x1, 0x48(%rax)
movq -0x1b0(%rbp), %rdi
addq $0x30, %rdi
addq $0x20, %rdi
callq 0x8c90
movq -0x1b0(%rbp), %rdi
addq $0x30, %rdi
addq $0x20, %rdi
movl $0x25, %esi
callq 0x8ea0
movq -0x1b0(%rbp), %rdi
addq $0x30, %rdi
addq $0x20, %rdi
leaq -0x88(%rbp), %rsi
callq 0x9100
leaq -0x98(%rbp), %rdi
callq 0x9310
leaq -0x70(%rbp), %rdi
callq 0x9310
leaq -0x88(%rbp), %rdi
callq 0x9310
jmp 0x28d3a
leaq 0x49758(%rip), %rdi     # 0x7245b
leaq 0x4f3c6(%rip), %rsi     # 0x780d0
movl $0x49b, %edx            # imm = 0x49B
leaq 0x4f5d8(%rip), %rcx     # 0x782ee
callq 0x30a0
leaq 0x49739(%rip), %rdi     # 0x7245b
leaq 0x4f3a7(%rip), %rsi     # 0x780d0
movl $0x49f, %edx            # imm = 0x49F
leaq 0x4f5b9(%rip), %rcx     # 0x782ee
callq 0x30a0
jmp 0x28d3c
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x2867c
addq $0x200, %rsp            # imm = 0x200
popq %rbp
retq
nopw %cs:(%rax,%rax)