// File: /workspace/github_c_makefile_star2_O2/Ihsoh[P]ilang/compiler/frontend/irgen.c
// Function: expr_result_cast
static void _expr_result_cast(
	IRGeneratorContext *ctx,
	_ExprResult *target_result,
	ParserASTNode *target_type_node,
	_ExprResult *source_result,
	ParserASTNode *source_type_node
) {
	assert(ctx);
	assert(target_result);
	assert(target_type_node);
	assert(source_result);
	assert(source_type_node);

	if (fe_sem_is_compatible_type(ctx->psrctx, target_type_node, source_type_node, true)) {
		goto not_need_to_cast;
	}

	uint8_t target_type = fe_sem_get_type_by_type_node(ctx->psrctx, target_type_node);
	uint8_t source_type = fe_sem_get_type_by_type_node(ctx->psrctx, source_type_node);

	ParserSymbol *func_symbol = ctx->func_symbol;
	assert(func_symbol);

	ResizableString rstr_tmp_label_val;
	rstr_init(&rstr_tmp_label_val);
	_generate_func_tmp_var(ctx, func_symbol, &rstr_tmp_label_val, target_type_node);

	ResizableString rstr_target_type;
	rstr_init(&rstr_target_type);
	_ir_type(ctx, &rstr_target_type, target_type_node);

	#define	_A(cmd)	\
		rstr_appendf(	\
			&(target_result->rstr_for_result),	\
			cmd" %s, %s;\n",	\
			RSTR_CSTR(&rstr_tmp_label_val),	\
			RSTR_CSTR(&(source_result->rstr_result))	\
		);	\
		_expr_result_set_result(	\
			target_result,	\
			RSTR_CSTR(&rstr_tmp_label_val)	\
		);

	if (fe_sem_is_signed_type(source_type)) {
		if (fe_sem_is_signed_type(target_type)) {
			size_t sz_target_type = fe_sem_get_primitive_type_size(target_type);
			size_t sz_source_type = fe_sem_get_primitive_type_size(source_type);

			if (sz_target_type < sz_source_type) {
				// 小的有符号整数 <- 大的有符号整数。
				_A("trunc")
			} else if (sz_target_type > sz_source_type) {
				// 大的有符号整数 <- 小的有符号整数。
				_A("sext")
			} else {
				_A("bitcast")
			}
		} else if (fe_sem_is_unsigned_type(target_type)) {
			size_t sz_target_type = fe_sem_get_primitive_type_size(target_type);
			size_t sz_source_type = fe_sem_get_primitive_type_size(source_type);

			if (sz_target_type < sz_source_type) {
				// 小的无符号整数 <- 大的有符号整数。
				_A("trunc")
			} else if (sz_target_type > sz_source_type) {
				// 大的无符号整数 <- 小的有符号整数。
				_A("sext")
			} else {
				_A("bitcast")
			}
		} else if (target_type == FE_TYPE_FLOAT) {
			// float <- 有符号整数。
			_A("sitofp")
		} else if (target_type == FE_TYPE_DOUBLE) {
			// double <- 有符号整数。
			_A("sitofp")
		} else if (target_type == FE_TYPE_POINTER) {
			// T* <- 有符号整数。
			_A("inttoptr")
		} else {
			assert(0);
		}
	} else if (fe_sem_is_unsigned_type(source_type)) {
		if (fe_sem_is_signed_type(target_type)) {
			size_t sz_target_type = fe_sem_get_primitive_type_size(target_type);
			size_t sz_source_type = fe_sem_get_primitive_type_size(source_type);

			if (sz_target_type < sz_source_type) {
				// 小的有符号整数 <- 大的无符号整数。
				_A("trunc")
			} else if (sz_target_type > sz_source_type) {
				// 大的有符号整数 <- 小的无符号整数。
				_A("zext")
			} else {
				_A("bitcast")
			}
		} else if (fe_sem_is_unsigned_type(target_type)) {
			size_t sz_target_type = fe_sem_get_primitive_type_size(target_type);
			size_t sz_source_type = fe_sem_get_primitive_type_size(source_type);

			if (sz_target_type < sz_source_type) {
				// 小的无符号整数 <- 大的无符号整数。
				_A("trunc")
			} else if (sz_target_type > sz_source_type) {
				// 大的无符号整数 <- 小的无符号整数。
				_A("zext")
			} else {
				_A("bitcast")
			}
		} else if (target_type == FE_TYPE_FLOAT) {
			// float <- 无符号整数。
			_A("uitofp")
		} else if (target_type == FE_TYPE_DOUBLE) {
			// double <- 无符号整数。
			_A("uitofp")
		} else if (target_type == FE_TYPE_POINTER) {
			// T* <- 无符号整数。
			_A("inttoptr")
		} else {
			assert(0);
		}
	} else if (source_type == FE_TYPE_FLOAT) {
		if (fe_sem_is_signed_type(target_type)) {
			// 有符号整数 <- float。
			_A("fptosi")
		} else if (fe_sem_is_unsigned_type(target_type)) {
			// 无符号整数 <- float。
			_A("fptoui")
		} else if (target_type == FE_TYPE_FLOAT) {
			// float <- float，不存在的。
			assert(0);
		} else if (target_type == FE_TYPE_DOUBLE) {
			// double <- float。
			_A("fpext")
		} else if (target_type == FE_TYPE_POINTER) {
			// T* <- float，不存在的。
			assert(0);
		} else {
			assert(0);
		}
	} else if (source_type == FE_TYPE_DOUBLE) {
		if (fe_sem_is_signed_type(target_type)) {
			// 有符号整数 <- double。
			_A("fptosi")
		} else if (fe_sem_is_unsigned_type(target_type)) {
			// 无符号整数 <- double。
			_A("fptoui")
		} else if (target_type == FE_TYPE_FLOAT) {
			// float <- double。
			_A("fptrunc")
		} else if (target_type == FE_TYPE_DOUBLE) {
			// double <- double，不存在的。
			assert(0);
		} else if (target_type == FE_TYPE_POINTER) {
			// T* <- double，不存在的。
			assert(0);
		} else {
			assert(0);
		}
	} else if (source_type == FE_TYPE_POINTER) {
		if (fe_sem_is_signed_type(target_type)) {
			// 有符号整数 <- T*。
			_A("ptrtoint")
		} else if (fe_sem_is_unsigned_type(target_type)) {
			// 无符号整数 <- T*。
			_A("ptrtoint")
		} else if (target_type == FE_TYPE_FLOAT) {
			// float <- T*，不存在的。
			assert(0);
		} else if (target_type == FE_TYPE_DOUBLE) {
			// double <- T*，不存在的。
			assert(0);
		} else if (target_type == FE_TYPE_POINTER) {
			// T* <- T*。
			_A("bitcast")
		} else {
			assert(0);
		}
	} else {
		assert(0);
	}

	rstr_free(&rstr_tmp_label_val);
	rstr_free(&rstr_target_type);
	return;

not_need_to_cast:
	_expr_result_set_result(target_result, RSTR_CSTR(&(source_result->rstr_result)));
	_expr_result_set_result_ptr(target_result, RSTR_CSTR(&(source_result->rstr_result_ptr)));

	#undef	_A
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
testq %rsi, %rsi
je 0xc71f
movq %rdx, %r12
testq %rdx, %rdx
je 0xc73e
movq %rcx, %rbx
testq %rcx, %rcx
je 0xc75d
movq %r8, %r15
testq %r8, %r8
je 0xc77c
movq %rsi, %r14
movq %rdi, %r13
movq (%rdi), %rdi
pushq $0x1
popq %rcx
movq %r12, %rsi
movq %r15, %rdx
callq 0x28347
testb %al, %al
je 0xc28e
movq 0x28(%rbx), %rsi
testq %rsi, %rsi
movq %rbx, %r15
leaq 0x33cba(%rip), %rbx     # 0x3ff16
cmoveq %rbx, %rsi
leaq 0x20(%r14), %rdi
callq 0x6e99
movq 0x38(%r15), %rsi
testq %rsi, %rsi
cmoveq %rbx, %rsi
addq $0x30, %r14
movq %r14, %rdi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x6e99
movq %rbx, -0x40(%rbp)
movq %r14, -0x50(%rbp)
movq (%r13), %rdi
movq %r12, %rsi
callq 0x2859e
movb %al, -0x41(%rbp)
movq (%r13), %rdi
movq %r15, %rsi
callq 0x2859e
movq 0x40(%r13), %rbx
testq %rbx, %rbx
je 0xc79b
movl %eax, %r15d
leaq -0x38(%rbp), %r14
movq %r14, %rdi
callq 0x6e1c
movq %r13, %rdi
movq %rbx, %rsi
movq %r14, %rdx
movq %r12, %rcx
callq 0xffa1
leaq -0x60(%rbp), %rbx
movq %rbx, %rdi
callq 0x6e1c
movq %rbx, %rdi
movq %r12, %rsi
callq 0xbd8f
movzbl %r15b, %r12d
movl %r12d, %edi
callq 0x282d9
testb %al, %al
je 0xc341
movb -0x41(%rbp), %bl
movzbl %bl, %r15d
movl %r15d, %edi
callq 0x282d9
testb %al, %al
je 0xc3cd
movl %r15d, %edi
callq 0x2829d
movq %rax, %r13
movl %r12d, %edi
callq 0x2829d
cmpq %rax, %r13
movq -0x50(%rbp), %r14
jb 0xc3fd
jmp 0xc4a6
movl %r12d, %edi
callq 0x282e9
testb %al, %al
movb -0x41(%rbp), %bl
je 0xc42a
movzbl %bl, %r15d
movl %r15d, %edi
callq 0x282d9
testb %al, %al
movq -0x50(%rbp), %r14
jne 0xc378
movl %r15d, %edi
callq 0x282e9
testb %al, %al
je 0xc5d4
movl %r15d, %edi
callq 0x2829d
movq %rax, %r13
movl %r12d, %edi
callq 0x2829d
cmpq %rax, %r13
jb 0xc3fd
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x33b78(%rip), %r15     # 0x3ff16
cmoveq %r15, %rdx
movq -0x40(%rbp), %rcx
movq 0x28(%rcx), %rcx
testq %rcx, %rcx
cmoveq %r15, %rcx
movq %r14, %rdi
addq $0x20, %r14
cmpq %rax, %r13
jbe 0xc4dc
leaq 0x33a70(%rip), %rsi     # 0x3fe38
jmp 0xc4e3
movl %r15d, %edi
callq 0x282e9
testb %al, %al
movq -0x50(%rbp), %r14
je 0xc500
movl %r15d, %edi
callq 0x2829d
movq %rax, %r13
movl %r12d, %edi
callq 0x2829d
cmpq %rax, %r13
jae 0xc4a6
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x33b0b(%rip), %rbx     # 0x3ff16
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x33a62(%rip), %rsi     # 0x3fe87
jmp 0xc6dd
cmpb $0x10, %r15b
movq -0x50(%rbp), %r14
je 0xc587
cmpl $0xb, %r12d
je 0xc546
cmpl $0xa, %r12d
jne 0xc7ba
movzbl %bl, %r15d
movl %r15d, %edi
callq 0x282d9
testb %al, %al
jne 0xc55a
movl %r15d, %edi
callq 0x282e9
testb %al, %al
jne 0xc64f
cmpb $0xb, %bl
jne 0xc7d9
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x33a8f(%rip), %rbx     # 0x3ff16
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x339d5(%rip), %rsi     # 0x3fe76
jmp 0xc6dd
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x33a62(%rip), %r15     # 0x3ff16
cmoveq %r15, %rdx
movq -0x40(%rbp), %rcx
movq 0x28(%rcx), %rcx
testq %rcx, %rcx
cmoveq %r15, %rcx
movq %r14, %rdi
addq $0x20, %r14
cmpq %rax, %r13
jbe 0xc4dc
leaq 0x3391d(%rip), %rsi     # 0x3fdf7
jmp 0xc4e3
leaq 0x33922(%rip), %rsi     # 0x3fe05
xorl %eax, %eax
callq 0x739a
movq -0x30(%rbp), %rax
testq %rax, %rax
cmovneq %rax, %r15
movq %r14, %rdi
movq %r15, %rsi
jmp 0xc6f9
cmpb $0x10, %bl
je 0xc616
cmpl $0xb, %r15d
je 0xc519
cmpl $0xa, %r15d
jne 0xc86a
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x339ef(%rip), %rbx     # 0x3ff16
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x338d5(%rip), %rsi     # 0x3fe16
jmp 0xc6dd
movzbl %bl, %r15d
movl %r15d, %edi
callq 0x282d9
testb %al, %al
je 0xc643
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x339ae(%rip), %rbx     # 0x3ff16
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x338d4(%rip), %rsi     # 0x3fe56
jmp 0xc6dd
movzbl %bl, %r15d
movl %r15d, %edi
callq 0x282d9
testb %al, %al
jne 0xc5a7
movl %r15d, %edi
callq 0x282e9
testb %al, %al
je 0xc6ac
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x33961(%rip), %rbx     # 0x3ff16
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x338c7(%rip), %rsi     # 0x3fe96
jmp 0xc6dd
cmpb $0x10, %bl
je 0xc616
cmpl $0xb, %r15d
je 0xc5e9
cmpl $0xa, %r15d
jne 0xc889
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x3391f(%rip), %rbx     # 0x3ff16
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x33835(%rip), %rsi     # 0x3fe46
jmp 0xc6dd
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x338f2(%rip), %rbx     # 0x3ff16
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x337e8(%rip), %rsi     # 0x3fe26
jmp 0xc6dd
movl %r15d, %edi
callq 0x282e9
testb %al, %al
je 0xc679
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x338b9(%rip), %rbx     # 0x3ff16
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x337ef(%rip), %rsi     # 0x3fe66
jmp 0xc6dd
cmpb $0xa, %bl
jne 0xc80c
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x33886(%rip), %rbx     # 0x3ff16
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x337db(%rip), %rsi     # 0x3fe85
jmp 0xc6dd
cmpb $0x10, %bl
jne 0xc83f
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x33853(%rip), %rbx     # 0x3ff16
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x33728(%rip), %rsi     # 0x3fe05
movq %r14, %rdi
xorl %eax, %eax
callq 0x739a
movq -0x30(%rbp), %rsi
testq %rsi, %rsi
cmoveq %rbx, %rsi
addq $0x20, %r14
movq %r14, %rdi
callq 0x6e99
leaq -0x38(%rbp), %rdi
callq 0x72b9
leaq -0x60(%rbp), %rdi
callq 0x72b9
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x33693(%rip), %rdi     # 0x3fdb9
leaq 0x31c47(%rip), %rsi     # 0x3e374
leaq 0x33618(%rip), %rcx     # 0x3fd4c
movl $0x201, %edx            # imm = 0x201
callq 0x30a0
leaq 0x33682(%rip), %rdi     # 0x3fdc7
leaq 0x31c28(%rip), %rsi     # 0x3e374
leaq 0x335f9(%rip), %rcx     # 0x3fd4c
movl $0x202, %edx            # imm = 0x202
callq 0x30a0
leaq 0x33674(%rip), %rdi     # 0x3fdd8
leaq 0x31c09(%rip), %rsi     # 0x3e374
leaq 0x335da(%rip), %rcx     # 0x3fd4c
movl $0x203, %edx            # imm = 0x203
callq 0x30a0
leaq 0x33663(%rip), %rdi     # 0x3fde6
leaq 0x31bea(%rip), %rsi     # 0x3e374
leaq 0x335bb(%rip), %rcx     # 0x3fd4c
movl $0x204, %edx            # imm = 0x204
callq 0x30a0
leaq 0x337d5(%rip), %rdi     # 0x3ff77
leaq 0x31bcb(%rip), %rsi     # 0x3e374
leaq 0x3359c(%rip), %rcx     # 0x3fd4c
movl $0x20e, %edx            # imm = 0x20E
callq 0x30a0
leaq 0x2fb9f(%rip), %rdi     # 0x3c360
leaq 0x31bac(%rip), %rsi     # 0x3e374
leaq 0x3357d(%rip), %rcx     # 0x3fd4c
movl $0x2ac, %edx            # imm = 0x2AC
callq 0x30a0
leaq 0x2fb80(%rip), %rdi     # 0x3c360
leaq 0x31b8d(%rip), %rsi     # 0x3e374
leaq 0x3355e(%rip), %rcx     # 0x3fd4c
cmpl $0x10, %r15d
je 0xc8a8
cmpl $0xa, %r15d
jne 0xc8b2
movl $0x27b, %edx            # imm = 0x27B
callq 0x30a0
leaq 0x2fb4d(%rip), %rdi     # 0x3c360
leaq 0x31b5a(%rip), %rsi     # 0x3e374
leaq 0x3352b(%rip), %rcx     # 0x3fd4c
cmpl $0xb, %r15d
je 0xc8bc
cmpl $0x10, %r15d
jne 0xc8c6
movl $0x294, %edx            # imm = 0x294
callq 0x30a0
leaq 0x2fb1a(%rip), %rdi     # 0x3c360
leaq 0x31b27(%rip), %rsi     # 0x3e374
leaq 0x334f8(%rip), %rcx     # 0x3fd4c
cmpl $0xb, %r15d
je 0xc8d0
cmpl $0xa, %r15d
jne 0xc8da
movl $0x2a1, %edx            # imm = 0x2A1
callq 0x30a0
leaq 0x2faef(%rip), %rdi     # 0x3c360
leaq 0x31afc(%rip), %rsi     # 0x3e374
leaq 0x334cd(%rip), %rcx     # 0x3fd4c
movl $0x249, %edx            # imm = 0x249
callq 0x30a0
leaq 0x2fad0(%rip), %rdi     # 0x3c360
leaq 0x31add(%rip), %rsi     # 0x3e374
leaq 0x334ae(%rip), %rcx     # 0x3fd4c
movl $0x270, %edx            # imm = 0x270
callq 0x30a0
movl $0x281, %edx            # imm = 0x281
callq 0x30a0
movl $0x283, %edx            # imm = 0x283
callq 0x30a0
movl $0x291, %edx            # imm = 0x291
callq 0x30a0
movl $0x296, %edx            # imm = 0x296
callq 0x30a0
movl $0x2a4, %edx            # imm = 0x2A4
callq 0x30a0
movl $0x2a9, %edx            # imm = 0x2A9
callq 0x30a0