// File: /workspace/github_c_makefile_star2_O1/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 0xd5c2
movq %rdx, %r12
testq %rdx, %rdx
je 0xd5e1
movq %rcx, %rbx
testq %rcx, %rcx
je 0xd600
movq %r8, %r15
testq %r8, %r8
je 0xd61f
movq %rsi, %r14
movq %rdi, %r13
movq (%rdi), %rdi
movq %r12, %rsi
movq %r15, %rdx
movl $0x1, %ecx
callq 0x2ad9d
testb %al, %al
je 0xd131
movq 0x28(%rbx), %rsi
testq %rsi, %rsi
movq %rbx, %r15
leaq 0x36dbb(%rip), %rbx     # 0x43eba
cmoveq %rbx, %rsi
leaq 0x20(%r14), %rdi
callq 0x75cf
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 0x75cf
movq %rbx, -0x40(%rbp)
movq %r14, -0x50(%rbp)
movq (%r13), %rdi
movq %r12, %rsi
callq 0x2b043
movb %al, -0x41(%rbp)
movq (%r13), %rdi
movq %r15, %rsi
callq 0x2b043
movq 0x40(%r13), %rbx
testq %rbx, %rbx
je 0xd63e
movl %eax, %r15d
leaq -0x38(%rbp), %r14
movq %r14, %rdi
callq 0x7548
movq %r13, %rdi
movq %rbx, %rsi
movq %r14, %rdx
movq %r12, %rcx
callq 0x10e9c
leaq -0x60(%rbp), %rbx
movq %rbx, %rdi
callq 0x7548
movq %rbx, %rdi
movq %r12, %rsi
callq 0xcbf5
movzbl %r15b, %r12d
movl %r12d, %edi
callq 0x2ad2f
testb %al, %al
je 0xd1e4
movb -0x41(%rbp), %bl
movzbl %bl, %r15d
movl %r15d, %edi
callq 0x2ad2f
testb %al, %al
je 0xd270
movl %r15d, %edi
callq 0x2acf3
movq %rax, %r13
movl %r12d, %edi
callq 0x2acf3
cmpq %rax, %r13
movq -0x50(%rbp), %r14
jb 0xd2a0
jmp 0xd349
movl %r12d, %edi
callq 0x2ad3f
testb %al, %al
movb -0x41(%rbp), %bl
je 0xd2cd
movzbl %bl, %r15d
movl %r15d, %edi
callq 0x2ad2f
testb %al, %al
movq -0x50(%rbp), %r14
jne 0xd21b
movl %r15d, %edi
callq 0x2ad3f
testb %al, %al
je 0xd477
movl %r15d, %edi
callq 0x2acf3
movq %rax, %r13
movl %r12d, %edi
callq 0x2acf3
cmpq %rax, %r13
jb 0xd2a0
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x36c79(%rip), %r15     # 0x43eba
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 0xd37f
leaq 0x36b71(%rip), %rsi     # 0x43ddc
jmp 0xd386
movl %r15d, %edi
callq 0x2ad3f
testb %al, %al
movq -0x50(%rbp), %r14
je 0xd3a3
movl %r15d, %edi
callq 0x2acf3
movq %rax, %r13
movl %r12d, %edi
callq 0x2acf3
cmpq %rax, %r13
jae 0xd349
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x36c0c(%rip), %rbx     # 0x43eba
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x36b63(%rip), %rsi     # 0x43e2b
jmp 0xd580
cmpb $0x10, %r15b
movq -0x50(%rbp), %r14
je 0xd42a
cmpl $0xb, %r12d
je 0xd3e9
cmpl $0xa, %r12d
jne 0xd65d
movzbl %bl, %r15d
movl %r15d, %edi
callq 0x2ad2f
testb %al, %al
jne 0xd3fd
movl %r15d, %edi
callq 0x2ad3f
testb %al, %al
jne 0xd4f2
cmpb $0xb, %bl
jne 0xd67c
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x36b90(%rip), %rbx     # 0x43eba
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x36ad6(%rip), %rsi     # 0x43e1a
jmp 0xd580
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x36b63(%rip), %r15     # 0x43eba
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 0xd37f
leaq 0x36a1e(%rip), %rsi     # 0x43d9b
jmp 0xd386
leaq 0x36a23(%rip), %rsi     # 0x43da9
xorl %eax, %eax
callq 0x7b31
movq -0x30(%rbp), %rax
testq %rax, %rax
cmovneq %rax, %r15
movq %r14, %rdi
movq %r15, %rsi
jmp 0xd59c
cmpb $0x10, %bl
je 0xd4b9
cmpl $0xb, %r15d
je 0xd3bc
cmpl $0xa, %r15d
jne 0xd70d
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x36af0(%rip), %rbx     # 0x43eba
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x369d6(%rip), %rsi     # 0x43dba
jmp 0xd580
movzbl %bl, %r15d
movl %r15d, %edi
callq 0x2ad2f
testb %al, %al
je 0xd4e6
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x36aaf(%rip), %rbx     # 0x43eba
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x369d5(%rip), %rsi     # 0x43dfa
jmp 0xd580
movzbl %bl, %r15d
movl %r15d, %edi
callq 0x2ad2f
testb %al, %al
jne 0xd44a
movl %r15d, %edi
callq 0x2ad3f
testb %al, %al
je 0xd54f
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x36a62(%rip), %rbx     # 0x43eba
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x369c8(%rip), %rsi     # 0x43e3a
jmp 0xd580
cmpb $0x10, %bl
je 0xd4b9
cmpl $0xb, %r15d
je 0xd48c
cmpl $0xa, %r15d
jne 0xd72c
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x36a20(%rip), %rbx     # 0x43eba
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x36936(%rip), %rsi     # 0x43dea
jmp 0xd580
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x369f3(%rip), %rbx     # 0x43eba
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x368e9(%rip), %rsi     # 0x43dca
jmp 0xd580
movl %r15d, %edi
callq 0x2ad3f
testb %al, %al
je 0xd51c
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x369ba(%rip), %rbx     # 0x43eba
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x368f0(%rip), %rsi     # 0x43e0a
jmp 0xd580
cmpb $0xa, %bl
jne 0xd6af
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x36987(%rip), %rbx     # 0x43eba
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x368dc(%rip), %rsi     # 0x43e29
jmp 0xd580
cmpb $0x10, %bl
jne 0xd6e2
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x36954(%rip), %rbx     # 0x43eba
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x36829(%rip), %rsi     # 0x43da9
movq %r14, %rdi
xorl %eax, %eax
callq 0x7b31
movq -0x30(%rbp), %rsi
testq %rsi, %rsi
cmoveq %rbx, %rsi
addq $0x20, %r14
movq %r14, %rdi
callq 0x75cf
leaq -0x38(%rbp), %rdi
callq 0x7a38
leaq -0x60(%rbp), %rdi
callq 0x7a38
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x36794(%rip), %rdi     # 0x43d5d
leaq 0x34d48(%rip), %rsi     # 0x42318
leaq 0x36719(%rip), %rcx     # 0x43cf0
movl $0x201, %edx            # imm = 0x201
callq 0x30a0
leaq 0x36783(%rip), %rdi     # 0x43d6b
leaq 0x34d29(%rip), %rsi     # 0x42318
leaq 0x366fa(%rip), %rcx     # 0x43cf0
movl $0x202, %edx            # imm = 0x202
callq 0x30a0
leaq 0x36775(%rip), %rdi     # 0x43d7c
leaq 0x34d0a(%rip), %rsi     # 0x42318
leaq 0x366db(%rip), %rcx     # 0x43cf0
movl $0x203, %edx            # imm = 0x203
callq 0x30a0
leaq 0x36764(%rip), %rdi     # 0x43d8a
leaq 0x34ceb(%rip), %rsi     # 0x42318
leaq 0x366bc(%rip), %rcx     # 0x43cf0
movl $0x204, %edx            # imm = 0x204
callq 0x30a0
leaq 0x368d6(%rip), %rdi     # 0x43f1b
leaq 0x34ccc(%rip), %rsi     # 0x42318
leaq 0x3669d(%rip), %rcx     # 0x43cf0
movl $0x20e, %edx            # imm = 0x20E
callq 0x30a0
leaq 0x32d20(%rip), %rdi     # 0x40384
leaq 0x34cad(%rip), %rsi     # 0x42318
leaq 0x3667e(%rip), %rcx     # 0x43cf0
movl $0x2ac, %edx            # imm = 0x2AC
callq 0x30a0
leaq 0x32d01(%rip), %rdi     # 0x40384
leaq 0x34c8e(%rip), %rsi     # 0x42318
leaq 0x3665f(%rip), %rcx     # 0x43cf0
cmpl $0x10, %r15d
je 0xd74b
cmpl $0xa, %r15d
jne 0xd755
movl $0x27b, %edx            # imm = 0x27B
callq 0x30a0
leaq 0x32cce(%rip), %rdi     # 0x40384
leaq 0x34c5b(%rip), %rsi     # 0x42318
leaq 0x3662c(%rip), %rcx     # 0x43cf0
cmpl $0xb, %r15d
je 0xd75f
cmpl $0x10, %r15d
jne 0xd769
movl $0x294, %edx            # imm = 0x294
callq 0x30a0
leaq 0x32c9b(%rip), %rdi     # 0x40384
leaq 0x34c28(%rip), %rsi     # 0x42318
leaq 0x365f9(%rip), %rcx     # 0x43cf0
cmpl $0xb, %r15d
je 0xd773
cmpl $0xa, %r15d
jne 0xd77d
movl $0x2a1, %edx            # imm = 0x2A1
callq 0x30a0
leaq 0x32c70(%rip), %rdi     # 0x40384
leaq 0x34bfd(%rip), %rsi     # 0x42318
leaq 0x365ce(%rip), %rcx     # 0x43cf0
movl $0x249, %edx            # imm = 0x249
callq 0x30a0
leaq 0x32c51(%rip), %rdi     # 0x40384
leaq 0x34bde(%rip), %rsi     # 0x42318
leaq 0x365af(%rip), %rcx     # 0x43cf0
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