// File: /workspace/github_c_makefile_star2_O0/Ihsoh[P]ilang/compiler/frontend/irgen_llvmir.c
// Function: ir_type
static void _ir_type(
	IRGeneratorLlvmirContext *ctx,
	ResizableString *rstr,
	ParserASTNode *node_type
) {
	assert(ctx);
	assert(rstr);
	assert(node_type);

	switch (node_type->type) {
		case FE_NODE_TYPE_CHAR: {
			rstr_append_with_cstr(rstr, "i8");
			break;
		}
		case FE_NODE_TYPE_INT8: {
			rstr_append_with_cstr(rstr, "i8");
			break;
		}
		case FE_NODE_TYPE_UINT8: {
			rstr_append_with_cstr(rstr, "i8");
			break;
		}
		case FE_NODE_TYPE_INT16: {
			rstr_append_with_cstr(rstr, "i16");
			break;
		}
		case FE_NODE_TYPE_UINT16: {
			rstr_append_with_cstr(rstr, "i16");
			break;
		}
		case FE_NODE_TYPE_INT32: {
			rstr_append_with_cstr(rstr, "i32");
			break;
		}
		case FE_NODE_TYPE_UINT32: {
			rstr_append_with_cstr(rstr, "i32");
			break;
		}
		case FE_NODE_TYPE_INT64: {
			rstr_append_with_cstr(rstr, "i64");
			break;
		}
		case FE_NODE_TYPE_UINT64: {
			rstr_append_with_cstr(rstr, "i64");
			break;
		}
		case FE_NODE_TYPE_FLOAT: {
			rstr_append_with_cstr(rstr, "float");
			break;
		}
		case FE_NODE_TYPE_DOUBLE: {
			rstr_append_with_cstr(rstr, "double");
			break;
		}
		case FE_NODE_TYPE_VA_LIST: {
			rstr_append_with_cstr(rstr, "%struct.va_list");
			break;
		}
		case FE_NODE_TYPE_STRUCT: {
			assert(node_type->nchilds == 1);

			ParserASTNode *node_id = node_type->childs[0];
			assert(node_id->type == FE_NODE_IDENTIFIER);

			rstr_append_with_cstr(rstr, "%struct.");
			rstr_append_with_raw(rstr, node_id->token->content, node_id->token->len);
			break;
		}
		case FE_NODE_TYPE_ARRAY: {
			assert(node_type->nchilds == 2);

			ParserASTNode *node_array_dims = node_type->childs[0];
			assert(node_array_dims->type == FE_NODE_TYPE_ARRAY_DIMS);
			assert(node_array_dims->nchilds > 0);

			ParserASTNode *node_t = node_type->childs[1];

			_ir_type(ctx, rstr, node_t);

			for (int i = node_array_dims->nchilds - 1; i >= 0; i--) {
				ParserASTNode *node_array_dim = node_array_dims->childs[i];
				assert(node_array_dim->type == FE_NODE_LITERAL_UINT);

				rstr_prepend_with_cstr(rstr, " x ");
				rstr_prepend_with_raw(rstr, node_array_dim->token->content, node_array_dim->token->len);
				rstr_prepend_with_cstr(rstr, "[");

				rstr_append_with_cstr(rstr, "]");
			}

			break;
		}
		case FE_NODE_TYPE_FUNC: {
			assert(node_type->nchilds == 1 || node_type->nchilds == 2);
			ParserASTNode *node_params = NULL;
			ParserASTNode *node_t = NULL;

			node_params = node_type->childs[0];
			assert(node_params->type == FE_NODE_FUNC_PARAMS);

			if (node_type->nchilds == 2) {
				node_t = node_type->childs[1];
			}

			if (node_t != NULL) {
				_ir_type(ctx, rstr, node_t);
			} else {
				rstr_append_with_cstr(rstr, "void");
			}

			rstr_append_with_cstr(rstr, " (");
			_ir_func_type_params(ctx, rstr, node_params);
			rstr_append_with_cstr(rstr, ")");
			break;
		}
		case FE_NODE_TYPE_POINTER: {
			assert(node_type->nchilds == 1);
			ParserASTNode *node_t = node_type->childs[0];

			_ir_type(ctx, rstr, node_t);

			rstr_append_with_cstr(rstr, "*");
			break;
		}
		case FE_NODE_TYPE_VOID: {
			// LLVM IR不允许有void指针类型，需要把void指针类型转换为i8指针类型。
			// 但是在方法的返回值类型的地方，是允许为void类型。
			if (node_type->parent != NULL
					&& node_type->parent->type == FE_NODE_TYPE_POINTER) {
				rstr_prepend_with_cstr(rstr, "i8");
			} else {
				rstr_prepend_with_cstr(rstr, "void");
			}
			break;
		}
		default: {
			assert(0);
			break;
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
cmpq $0x0, -0x8(%rbp)
je 0x299fd
jmp 0x29a1c
leaq 0x52b52(%rip), %rdi     # 0x7c556
leaq 0x4e6c5(%rip), %rsi     # 0x780d0
movl $0x269, %edx            # imm = 0x269
leaq 0x4e970(%rip), %rcx     # 0x78387
callq 0x30a0
cmpq $0x0, -0x10(%rbp)
je 0x29a25
jmp 0x29a44
leaq 0x490e2(%rip), %rdi     # 0x72b0e
leaq 0x4e69d(%rip), %rsi     # 0x780d0
movl $0x26a, %edx            # imm = 0x26A
leaq 0x4e948(%rip), %rcx     # 0x78387
callq 0x30a0
cmpq $0x0, -0x18(%rbp)
je 0x29a4d
jmp 0x29a6c
leaq 0x4acdf(%rip), %rdi     # 0x74733
leaq 0x4e675(%rip), %rsi     # 0x780d0
movl $0x26b, %edx            # imm = 0x26B
leaq 0x4e920(%rip), %rcx     # 0x78387
callq 0x30a0
movq -0x18(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x5c(%rbp)
subl $0x400, %eax            # imm = 0x400
je 0x29b85
jmp 0x29a82
movl -0x5c(%rbp), %eax
subl $0x401, %eax            # imm = 0x401
je 0x29b9a
jmp 0x29a92
movl -0x5c(%rbp), %eax
subl $0x402, %eax            # imm = 0x402
je 0x29bc4
jmp 0x29aa2
movl -0x5c(%rbp), %eax
subl $0x403, %eax            # imm = 0x403
je 0x29bee
jmp 0x29ab2
movl -0x5c(%rbp), %eax
subl $0x404, %eax            # imm = 0x404
je 0x29c18
jmp 0x29ac2
movl -0x5c(%rbp), %eax
subl $0x405, %eax            # imm = 0x405
je 0x29baf
jmp 0x29ad2
movl -0x5c(%rbp), %eax
subl $0x406, %eax            # imm = 0x406
je 0x29bd9
jmp 0x29ae2
movl -0x5c(%rbp), %eax
subl $0x407, %eax            # imm = 0x407
je 0x29c03
jmp 0x29af2
movl -0x5c(%rbp), %eax
subl $0x408, %eax            # imm = 0x408
je 0x29c2d
jmp 0x29b02
movl -0x5c(%rbp), %eax
subl $0x409, %eax            # imm = 0x409
je 0x29c42
jmp 0x29b12
movl -0x5c(%rbp), %eax
subl $0x40a, %eax            # imm = 0x40A
je 0x29c57
jmp 0x29b22
movl -0x5c(%rbp), %eax
subl $0x40b, %eax            # imm = 0x40B
je 0x29c6c
jmp 0x29b32
movl -0x5c(%rbp), %eax
subl $0x410, %eax            # imm = 0x410
je 0x29c81
jmp 0x29b42
movl -0x5c(%rbp), %eax
subl $0x420, %eax            # imm = 0x420
je 0x29d1d
jmp 0x29b52
movl -0x5c(%rbp), %eax
subl $0x430, %eax            # imm = 0x430
je 0x29e8b
jmp 0x29b62
movl -0x5c(%rbp), %eax
subl $0x440, %eax            # imm = 0x440
je 0x29f86
jmp 0x29b72
movl -0x5c(%rbp), %eax
subl $0x4ff, %eax            # imm = 0x4FF
je 0x29fe3
jmp 0x2a022
movq -0x10(%rbp), %rdi
leaq 0x4e845(%rip), %rsi     # 0x783d5
callq 0x8d70
jmp 0x2a041
movq -0x10(%rbp), %rdi
leaq 0x4e830(%rip), %rsi     # 0x783d5
callq 0x8d70
jmp 0x2a041
movq -0x10(%rbp), %rdi
leaq 0x4e81b(%rip), %rsi     # 0x783d5
callq 0x8d70
jmp 0x2a041
movq -0x10(%rbp), %rdi
leaq 0x4e809(%rip), %rsi     # 0x783d8
callq 0x8d70
jmp 0x2a041
movq -0x10(%rbp), %rdi
leaq 0x4e7f4(%rip), %rsi     # 0x783d8
callq 0x8d70
jmp 0x2a041
movq -0x10(%rbp), %rdi
leaq 0x4e7e3(%rip), %rsi     # 0x783dc
callq 0x8d70
jmp 0x2a041
movq -0x10(%rbp), %rdi
leaq 0x4e7ce(%rip), %rsi     # 0x783dc
callq 0x8d70
jmp 0x2a041
movq -0x10(%rbp), %rdi
leaq 0x4e7bd(%rip), %rsi     # 0x783e0
callq 0x8d70
jmp 0x2a041
movq -0x10(%rbp), %rdi
leaq 0x4e7a8(%rip), %rsi     # 0x783e0
callq 0x8d70
jmp 0x2a041
movq -0x10(%rbp), %rdi
leaq 0x4ab10(%rip), %rsi     # 0x7475d
callq 0x8d70
jmp 0x2a041
movq -0x10(%rbp), %rdi
leaq 0x4ab01(%rip), %rsi     # 0x74763
callq 0x8d70
jmp 0x2a041
movq -0x10(%rbp), %rdi
leaq 0x4e76d(%rip), %rsi     # 0x783e4
callq 0x8d70
jmp 0x2a041
movq -0x18(%rbp), %rax
cmpl $0x1, 0x44(%rax)
jne 0x29c8d
jmp 0x29cac
leaq 0x4aae0(%rip), %rdi     # 0x74774
leaq 0x4e435(%rip), %rsi     # 0x780d0
movl $0x29f, %edx            # imm = 0x29F
leaq 0x4e6e0(%rip), %rcx     # 0x78387
callq 0x30a0
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq (%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x200, (%rax)          # imm = 0x200
jne 0x29cc9
jmp 0x29ce8
leaq 0x4aabc(%rip), %rdi     # 0x7478c
leaq 0x4e3f9(%rip), %rsi     # 0x780d0
movl $0x2a2, %edx            # imm = 0x2A2
leaq 0x4e6a4(%rip), %rcx     # 0x78387
callq 0x30a0
movq -0x10(%rbp), %rdi
leaq 0x4e701(%rip), %rsi     # 0x783f4
callq 0x8d70
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rsi
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rax
movl 0x4(%rax), %edx
callq 0x8f90
jmp 0x2a041
movq -0x18(%rbp), %rax
cmpl $0x2, 0x44(%rax)
jne 0x29d29
jmp 0x29d48
leaq 0x4ab18(%rip), %rdi     # 0x74848
leaq 0x4e399(%rip), %rsi     # 0x780d0
movl $0x2a9, %edx            # imm = 0x2A9
leaq 0x4e644(%rip), %rcx     # 0x78387
callq 0x30a0
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq (%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpl $0x421, (%rax)          # imm = 0x421
jne 0x29d65
jmp 0x29d84
leaq 0x4aa44(%rip), %rdi     # 0x747b0
leaq 0x4e35d(%rip), %rsi     # 0x780d0
movl $0x2ac, %edx            # imm = 0x2AC
leaq 0x4e608(%rip), %rcx     # 0x78387
callq 0x30a0
movq -0x28(%rbp), %rax
cmpl $0x0, 0x44(%rax)
jle 0x29d90
jmp 0x29daf
leaq 0x4aa4a(%rip), %rdi     # 0x747e1
leaq 0x4e332(%rip), %rsi     # 0x780d0
movl $0x2ad, %edx            # imm = 0x2AD
leaq 0x4e5dd(%rip), %rcx     # 0x78387
callq 0x30a0
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x299e0
movq -0x28(%rbp), %rax
movl 0x44(%rax), %eax
subl $0x1, %eax
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
jl 0x29e86
movq -0x28(%rbp), %rax
movq 0x48(%rax), %rax
movslq -0x34(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
cmpl $0x300, (%rax)          # imm = 0x300
jne 0x29e09
jmp 0x29e28
leaq 0x4a9ee(%rip), %rdi     # 0x747fe
leaq 0x4e2b9(%rip), %rsi     # 0x780d0
movl $0x2b5, %edx            # imm = 0x2B5
leaq 0x4e564(%rip), %rcx     # 0x78387
callq 0x30a0
movq -0x10(%rbp), %rdi
leaq 0x4e5ca(%rip), %rsi     # 0x783fd
callq 0x9aa0
movq -0x10(%rbp), %rdi
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rsi
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movl 0x4(%rax), %edx
callq 0x9b10
movq -0x10(%rbp), %rdi
leaq 0x4a9c8(%rip), %rsi     # 0x7482b
callq 0x9aa0
movq -0x10(%rbp), %rdi
leaq 0x552aa(%rip), %rsi     # 0x7f11d
callq 0x8d70
movl -0x34(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x29ddd
jmp 0x2a041
movq -0x18(%rbp), %rax
cmpl $0x1, 0x44(%rax)
je 0x29e9f
movq -0x18(%rbp), %rax
cmpl $0x2, 0x44(%rax)
jne 0x29ea1
jmp 0x29ec0
leaq 0x4a985(%rip), %rdi     # 0x7482d
leaq 0x4e221(%rip), %rsi     # 0x780d0
movl $0x2c1, %edx            # imm = 0x2C1
leaq 0x4e4cc(%rip), %rcx     # 0x78387
callq 0x30a0
movq $0x0, -0x48(%rbp)
movq $0x0, -0x50(%rbp)
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
cmpl $0xa01, (%rax)          # imm = 0xA01
jne 0x29eed
jmp 0x29f0c
leaq 0x4a96c(%rip), %rdi     # 0x74860
leaq 0x4e1d5(%rip), %rsi     # 0x780d0
movl $0x2c6, %edx            # imm = 0x2C6
leaq 0x4e480(%rip), %rcx     # 0x78387
callq 0x30a0
movq -0x18(%rbp), %rax
cmpl $0x2, 0x44(%rax)
jne 0x29f26
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
je 0x29f40
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x50(%rbp), %rdx
callq 0x299e0
jmp 0x29f50
movq -0x10(%rbp), %rdi
leaq 0x4e4b6(%rip), %rsi     # 0x78401
callq 0x8d70
movq -0x10(%rbp), %rdi
leaq 0x4db01(%rip), %rsi     # 0x77a5c
callq 0x8d70
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x48(%rbp), %rdx
callq 0x2c740
movq -0x10(%rbp), %rdi
leaq 0x4d022(%rip), %rsi     # 0x76f9e
callq 0x8d70
jmp 0x2a041
movq -0x18(%rbp), %rax
cmpl $0x1, 0x44(%rax)
jne 0x29f92
jmp 0x29fb1
leaq 0x4a7db(%rip), %rdi     # 0x74774
leaq 0x4e130(%rip), %rsi     # 0x780d0
movl $0x2d8, %edx            # imm = 0x2D8
leaq 0x4e3db(%rip), %rcx     # 0x78387
callq 0x30a0
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq (%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x58(%rbp), %rdx
callq 0x299e0
movq -0x10(%rbp), %rdi
leaq 0x4d05f(%rip), %rsi     # 0x7703b
callq 0x8d70
jmp 0x2a041
movq -0x18(%rbp), %rax
cmpq $0x0, 0x30(%rax)
je 0x2a010
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rax
cmpl $0x440, (%rax)          # imm = 0x440
jne 0x2a010
movq -0x10(%rbp), %rdi
leaq 0x4e3cc(%rip), %rsi     # 0x783d5
callq 0x9aa0
jmp 0x2a020
movq -0x10(%rbp), %rdi
leaq 0x4e3e6(%rip), %rsi     # 0x78401
callq 0x9aa0
jmp 0x2a041
leaq 0x48432(%rip), %rdi     # 0x7245b
leaq 0x4e0a0(%rip), %rsi     # 0x780d0
movl $0x2ec, %edx            # imm = 0x2EC
leaq 0x4e34b(%rip), %rcx     # 0x78387
callq 0x30a0
addq $0x60, %rsp
popq %rbp
retq
nopw (%rax,%rax)