// File: /workspace/github_c_makefile_star2_O3/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 0xd343
movq %rdx, %r12
testq %rdx, %rdx
je 0xd362
movq %rcx, %rbx
testq %rcx, %rcx
je 0xd381
movq %r8, %r15
testq %r8, %r8
je 0xd3a0
movq %rsi, %r14
movq %rdi, %r13
movq (%rdi), %rdi
movq %r12, %rsi
movq %r15, %rdx
movl $0x1, %ecx
callq 0x2a4b2
testb %al, %al
je 0xceb2
movq 0x28(%rbx), %rsi
testq %rsi, %rsi
movq %rbx, %r15
leaq 0x36086(%rip), %rbx     # 0x42f06
cmoveq %rbx, %rsi
leaq 0x20(%r14), %rdi
callq 0x73db
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 0x73db
movq %rbx, -0x40(%rbp)
movq %r14, -0x50(%rbp)
movq (%r13), %rdi
movq %r12, %rsi
callq 0x2a70b
movb %al, -0x41(%rbp)
movq (%r13), %rdi
movq %r15, %rsi
callq 0x2a70b
movq 0x40(%r13), %rbx
testq %rbx, %rbx
je 0xd3bf
movl %eax, %r15d
leaq -0x38(%rbp), %r14
movq %r14, %rdi
callq 0x7354
movq %r13, %rdi
movq %rbx, %rsi
movq %r14, %rdx
movq %r12, %rcx
callq 0x10c3e
leaq -0x60(%rbp), %rbx
movq %rbx, %rdi
callq 0x7354
movq %rbx, %rdi
movq %r12, %rsi
callq 0xc991
movzbl %r15b, %r12d
movl %r12d, %edi
callq 0x2a444
testb %al, %al
je 0xcf65
movb -0x41(%rbp), %bl
movzbl %bl, %r15d
movl %r15d, %edi
callq 0x2a444
testb %al, %al
je 0xcff1
movl %r15d, %edi
callq 0x2a408
movq %rax, %r13
movl %r12d, %edi
callq 0x2a408
cmpq %rax, %r13
movq -0x50(%rbp), %r14
jb 0xd021
jmp 0xd0ca
movl %r12d, %edi
callq 0x2a454
testb %al, %al
movb -0x41(%rbp), %bl
je 0xd04e
movzbl %bl, %r15d
movl %r15d, %edi
callq 0x2a444
testb %al, %al
movq -0x50(%rbp), %r14
jne 0xcf9c
movl %r15d, %edi
callq 0x2a454
testb %al, %al
je 0xd1f8
movl %r15d, %edi
callq 0x2a408
movq %rax, %r13
movl %r12d, %edi
callq 0x2a408
cmpq %rax, %r13
jb 0xd021
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x35f44(%rip), %r15     # 0x42f06
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 0xd100
leaq 0x35e3c(%rip), %rsi     # 0x42e28
jmp 0xd107
movl %r15d, %edi
callq 0x2a454
testb %al, %al
movq -0x50(%rbp), %r14
je 0xd124
movl %r15d, %edi
callq 0x2a408
movq %rax, %r13
movl %r12d, %edi
callq 0x2a408
cmpq %rax, %r13
jae 0xd0ca
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x35ed7(%rip), %rbx     # 0x42f06
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x35e2e(%rip), %rsi     # 0x42e77
jmp 0xd301
cmpb $0x10, %r15b
movq -0x50(%rbp), %r14
je 0xd1ab
cmpl $0xb, %r12d
je 0xd16a
cmpl $0xa, %r12d
jne 0xd3de
movzbl %bl, %r15d
movl %r15d, %edi
callq 0x2a444
testb %al, %al
jne 0xd17e
movl %r15d, %edi
callq 0x2a454
testb %al, %al
jne 0xd273
cmpb $0xb, %bl
jne 0xd3fd
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x35e5b(%rip), %rbx     # 0x42f06
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x35da1(%rip), %rsi     # 0x42e66
jmp 0xd301
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x35e2e(%rip), %r15     # 0x42f06
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 0xd100
leaq 0x35ce9(%rip), %rsi     # 0x42de7
jmp 0xd107
leaq 0x35cee(%rip), %rsi     # 0x42df5
xorl %eax, %eax
callq 0x7945
movq -0x30(%rbp), %rax
testq %rax, %rax
cmovneq %rax, %r15
movq %r14, %rdi
movq %r15, %rsi
jmp 0xd31d
cmpb $0x10, %bl
je 0xd23a
cmpl $0xb, %r15d
je 0xd13d
cmpl $0xa, %r15d
jne 0xd48e
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x35dbb(%rip), %rbx     # 0x42f06
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x35ca1(%rip), %rsi     # 0x42e06
jmp 0xd301
movzbl %bl, %r15d
movl %r15d, %edi
callq 0x2a444
testb %al, %al
je 0xd267
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x35d7a(%rip), %rbx     # 0x42f06
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x35ca0(%rip), %rsi     # 0x42e46
jmp 0xd301
movzbl %bl, %r15d
movl %r15d, %edi
callq 0x2a444
testb %al, %al
jne 0xd1cb
movl %r15d, %edi
callq 0x2a454
testb %al, %al
je 0xd2d0
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x35d2d(%rip), %rbx     # 0x42f06
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x35c93(%rip), %rsi     # 0x42e86
jmp 0xd301
cmpb $0x10, %bl
je 0xd23a
cmpl $0xb, %r15d
je 0xd20d
cmpl $0xa, %r15d
jne 0xd4ad
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x35ceb(%rip), %rbx     # 0x42f06
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x35c01(%rip), %rsi     # 0x42e36
jmp 0xd301
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x35cbe(%rip), %rbx     # 0x42f06
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x35bb4(%rip), %rsi     # 0x42e16
jmp 0xd301
movl %r15d, %edi
callq 0x2a454
testb %al, %al
je 0xd29d
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x35c85(%rip), %rbx     # 0x42f06
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x35bbb(%rip), %rsi     # 0x42e56
jmp 0xd301
cmpb $0xa, %bl
jne 0xd430
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x35c52(%rip), %rbx     # 0x42f06
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x35ba7(%rip), %rsi     # 0x42e75
jmp 0xd301
cmpb $0x10, %bl
jne 0xd463
movq -0x30(%rbp), %rdx
testq %rdx, %rdx
leaq 0x35c1f(%rip), %rbx     # 0x42f06
cmoveq %rbx, %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %rbx, %rcx
leaq 0x35af4(%rip), %rsi     # 0x42df5
movq %r14, %rdi
xorl %eax, %eax
callq 0x7945
movq -0x30(%rbp), %rsi
testq %rsi, %rsi
cmoveq %rbx, %rsi
addq $0x20, %r14
movq %r14, %rdi
callq 0x73db
leaq -0x38(%rbp), %rdi
callq 0x7852
leaq -0x60(%rbp), %rdi
callq 0x7852
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x35a5f(%rip), %rdi     # 0x42da9
leaq 0x34013(%rip), %rsi     # 0x41364
leaq 0x359e4(%rip), %rcx     # 0x42d3c
movl $0x201, %edx            # imm = 0x201
callq 0x30a0
leaq 0x35a4e(%rip), %rdi     # 0x42db7
leaq 0x33ff4(%rip), %rsi     # 0x41364
leaq 0x359c5(%rip), %rcx     # 0x42d3c
movl $0x202, %edx            # imm = 0x202
callq 0x30a0
leaq 0x35a40(%rip), %rdi     # 0x42dc8
leaq 0x33fd5(%rip), %rsi     # 0x41364
leaq 0x359a6(%rip), %rcx     # 0x42d3c
movl $0x203, %edx            # imm = 0x203
callq 0x30a0
leaq 0x35a2f(%rip), %rdi     # 0x42dd6
leaq 0x33fb6(%rip), %rsi     # 0x41364
leaq 0x35987(%rip), %rcx     # 0x42d3c
movl $0x204, %edx            # imm = 0x204
callq 0x30a0
leaq 0x35ba1(%rip), %rdi     # 0x42f67
leaq 0x33f97(%rip), %rsi     # 0x41364
leaq 0x35968(%rip), %rcx     # 0x42d3c
movl $0x20e, %edx            # imm = 0x20E
callq 0x30a0
leaq 0x31f7b(%rip), %rdi     # 0x3f360
leaq 0x33f78(%rip), %rsi     # 0x41364
leaq 0x35949(%rip), %rcx     # 0x42d3c
movl $0x2ac, %edx            # imm = 0x2AC
callq 0x30a0
leaq 0x31f5c(%rip), %rdi     # 0x3f360
leaq 0x33f59(%rip), %rsi     # 0x41364
leaq 0x3592a(%rip), %rcx     # 0x42d3c
cmpl $0x10, %r15d
je 0xd4cc
cmpl $0xa, %r15d
jne 0xd4d6
movl $0x27b, %edx            # imm = 0x27B
callq 0x30a0
leaq 0x31f29(%rip), %rdi     # 0x3f360
leaq 0x33f26(%rip), %rsi     # 0x41364
leaq 0x358f7(%rip), %rcx     # 0x42d3c
cmpl $0xb, %r15d
je 0xd4e0
cmpl $0x10, %r15d
jne 0xd4ea
movl $0x294, %edx            # imm = 0x294
callq 0x30a0
leaq 0x31ef6(%rip), %rdi     # 0x3f360
leaq 0x33ef3(%rip), %rsi     # 0x41364
leaq 0x358c4(%rip), %rcx     # 0x42d3c
cmpl $0xb, %r15d
je 0xd4f4
cmpl $0xa, %r15d
jne 0xd4fe
movl $0x2a1, %edx            # imm = 0x2A1
callq 0x30a0
leaq 0x31ecb(%rip), %rdi     # 0x3f360
leaq 0x33ec8(%rip), %rsi     # 0x41364
leaq 0x35899(%rip), %rcx     # 0x42d3c
movl $0x249, %edx            # imm = 0x249
callq 0x30a0
leaq 0x31eac(%rip), %rdi     # 0x3f360
leaq 0x33ea9(%rip), %rsi     # 0x41364
leaq 0x3587a(%rip), %rcx     # 0x42d3c
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