// File: /workspace/github_c_makefile_star2_O3/Ihsoh[P]ilang/compiler/frontend/irgen_llvmir.c
// Function: expr_result_cast
static void _expr_result_cast(
	IRGeneratorLlvmirContext *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);

	if (fe_sem_is_integer_type(target_type)
			&& fe_sem_is_integer_type(source_type)
			&& fe_sem_get_primitive_type_size(target_type) == fe_sem_get_primitive_type_size(source_type)) {
		goto not_need_to_cast;
	}

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

	ResizableString rstr_tmp_label_val;
	rstr_init(&rstr_tmp_label_val);
	_generate_func_tmp(ctx, func_symbol, &rstr_tmp_label_val);

	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),	\
			"%s = "cmd" %s to %s\n",	\
			RSTR_CSTR(&rstr_tmp_label_val),	\
			RSTR_CSTR(&(source_result->rstr_result)),	\
			RSTR_CSTR(&rstr_target_type)	\
		);	\
		_expr_result_set_result(	\
			target_result,	\
			RSTR_CSTR(&rstr_target_type),	\
			RSTR_CSTR(&rstr_tmp_label_val)	\
		);

	if (fe_sem_is_signed_type(source_type)) {
		if (fe_sem_is_signed_type(target_type)) {
			if (fe_sem_get_primitive_type_size(target_type) < fe_sem_get_primitive_type_size(source_type)) {
				// 小的有符号整数 <- 大的有符号整数。
				_A("trunc")
			} else {
				// 大的有符号整数 <- 小的有符号整数。
				_A("sext")
			}
		} else if (fe_sem_is_unsigned_type(target_type)) {
			if (fe_sem_get_primitive_type_size(target_type) < fe_sem_get_primitive_type_size(source_type)) {
				// 小的无符号整数 <- 大的有符号整数。
				_A("trunc")
			} else {
				// 大的无符号整数 <- 小的有符号整数。
				_A("sext")
			}
		} 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)) {
			if (fe_sem_get_primitive_type_size(target_type) < fe_sem_get_primitive_type_size(source_type)) {
				// 小的有符号整数 <- 大的无符号整数。
				_A("trunc")
			} else {
				// 大的有符号整数 <- 小的无符号整数。
				_A("zext")
			}
		} else if (fe_sem_is_unsigned_type(target_type)) {
			if (fe_sem_get_primitive_type_size(target_type) < fe_sem_get_primitive_type_size(source_type)) {
				// 小的无符号整数 <- 大的无符号整数。
				_A("trunc")
			} else {
				// 大的无符号整数 <- 小的无符号整数。
				_A("zext")
			}
		} 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_type)),
		RSTR_CSTR(&(source_result->rstr_result_val))
	);
	_expr_result_set_result_ptr(
		target_result,
		RSTR_CSTR(&(source_result->rstr_result_ptr_type)),
		RSTR_CSTR(&(source_result->rstr_result_ptr_val))
	);

	#undef	_A
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rcx, -0x38(%rbp)
testq %rsi, %rsi
je 0x1a1b5
movq %rdx, %rbx
testq %rdx, %rdx
je 0x1a1d4
movq %rsi, -0x40(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x1a1f3
movq %r8, %r12
testq %r8, %r8
je 0x1a212
movq %rdi, %r15
movq (%rdi), %rdi
movq %rbx, %rsi
movq %r12, %rdx
movl $0x1, %ecx
callq 0x2a4b2
testb %al, %al
je 0x19c7b
movq -0x38(%rbp), %r14
movq 0x38(%r14), %rsi
testq %rsi, %rsi
leaq 0x292d2(%rip), %rbx     # 0x42f06
cmoveq %rbx, %rsi
movq 0x48(%r14), %rdx
testq %rdx, %rdx
cmoveq %rbx, %rdx
movq -0x40(%rbp), %r15
movq %r15, %rdi
callq 0x1def5
movq 0x68(%r14), %rsi
testq %rsi, %rsi
cmoveq %rbx, %rsi
movq 0x78(%r14), %rdx
testq %rdx, %rdx
cmoveq %rbx, %rdx
movq %r15, %rdi
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1dff7
movq (%r15), %rdi
movq %rbx, %rsi
callq 0x2a70b
movl %eax, %r13d
movq (%r15), %rdi
movq %r12, %rsi
callq 0x2a70b
movl %eax, %r14d
movb %r13b, -0x29(%rbp)
movzbl %r13b, %r13d
movl %r13d, %edi
callq 0x2a465
movb %r14b, -0x41(%rbp)
movzbl %r14b, %r14d
testb %al, %al
je 0x19cdb
movl %r14d, %edi
callq 0x2a465
testb %al, %al
je 0x19cdb
movl %r13d, %edi
callq 0x2a408
movq %rax, %r12
movl %r14d, %edi
callq 0x2a408
cmpq %rax, %r12
je 0x19c22
movl %r13d, -0x48(%rbp)
movq 0x40(%r15), %r12
testq %r12, %r12
je 0x1a231
leaq -0x68(%rbp), %r15
movq %r15, %rdi
callq 0x7354
movl 0x54(%r12), %edx
leal 0x1(%rdx), %eax
movl %eax, 0x54(%r12)
leaq 0x2b45e(%rip), %rsi     # 0x4516a
movq %r15, %rdi
xorl %eax, %eax
callq 0x7945
leaq -0x58(%rbp), %r15
movq %r15, %rdi
callq 0x7354
movq %r15, %rdi
movq %rbx, %rsi
callq 0x19540
movl %r14d, %edi
callq 0x2a444
testb %al, %al
je 0x19da5
movl -0x48(%rbp), %ebx
movl %ebx, %edi
callq 0x2a444
testb %al, %al
jne 0x19d56
movl %ebx, %edi
callq 0x2a454
testb %al, %al
je 0x19e8a
movl %ebx, %edi
callq 0x2a408
movq %rax, %rbx
movl %r14d, %edi
callq 0x2a408
movq -0x60(%rbp), %rdx
testq %rdx, %rdx
leaq 0x29190(%rip), %rsi     # 0x42f06
cmoveq %rsi, %rdx
movq -0x38(%rbp), %rcx
movq 0x28(%rcx), %rcx
testq %rcx, %rcx
cmoveq %rsi, %rcx
movq -0x50(%rbp), %r8
testq %r8, %r8
cmoveq %rsi, %r8
cmpq %rax, %rbx
jb 0x19e15
leaq 0x2c2a8(%rip), %rsi     # 0x46048
jmp 0x19ff8
movl %r14d, %edi
callq 0x2a454
testb %al, %al
movl -0x48(%rbp), %ebx
je 0x19e21
movl %ebx, %edi
callq 0x2a444
testb %al, %al
jne 0x19dce
movl %ebx, %edi
callq 0x2a454
testb %al, %al
je 0x19f78
movl %ebx, %edi
callq 0x2a408
movq %rax, %rbx
movl %r14d, %edi
callq 0x2a408
movq -0x60(%rbp), %rdx
testq %rdx, %rdx
leaq 0x29118(%rip), %rsi     # 0x42f06
cmoveq %rsi, %rdx
movq -0x38(%rbp), %rcx
movq 0x28(%rcx), %rcx
testq %rcx, %rcx
cmoveq %rsi, %rcx
movq -0x50(%rbp), %r8
testq %r8, %r8
cmoveq %rsi, %r8
cmpq %rax, %rbx
jae 0x19ede
leaq 0x2c217(%rip), %rsi     # 0x46033
jmp 0x19ff8
cmpb $0x10, -0x41(%rbp)
je 0x19f31
cmpl $0xb, %r14d
je 0x19eea
cmpl $0xa, %r14d
jne 0x1a250
movl %ebx, %edi
callq 0x2a444
testb %al, %al
movq -0x40(%rbp), %r15
je 0x1a0ee
movq -0x60(%rbp), %rdx
testq %rdx, %rdx
leaq 0x290a6(%rip), %rax     # 0x42f06
cmoveq %rax, %rdx
movq -0x38(%rbp), %rcx
movq 0x28(%rcx), %rcx
testq %rcx, %rcx
cmoveq %rax, %rcx
movq -0x50(%rbp), %r8
testq %r8, %r8
cmoveq %rax, %r8
leaq 0x2c22f(%rip), %rsi     # 0x460b4
jmp 0x19ffc
cmpb $0x10, -0x29(%rbp)
je 0x19fc5
cmpl $0xb, %ebx
movq -0x40(%rbp), %r15
je 0x19ea6
cmpl $0xa, %ebx
jne 0x1a305
movq -0x60(%rbp), %rdx
testq %rdx, %rdx
leaq 0x29052(%rip), %rax     # 0x42f06
cmoveq %rax, %rdx
movq -0x38(%rbp), %rcx
movq 0x28(%rcx), %rcx
testq %rcx, %rcx
cmoveq %rax, %rcx
movq -0x50(%rbp), %r8
testq %r8, %r8
cmoveq %rax, %r8
leaq 0x2c183(%rip), %rsi     # 0x4605c
jmp 0x19ffc
leaq 0x2c1a5(%rip), %rsi     # 0x4608a
jmp 0x19ff8
movl %ebx, %edi
callq 0x2a444
testb %al, %al
je 0x1a052
movq -0x60(%rbp), %rdx
testq %rdx, %rdx
leaq 0x28fff(%rip), %rax     # 0x42f06
cmoveq %rax, %rdx
movq -0x38(%rbp), %rcx
movq 0x28(%rcx), %rcx
testq %rcx, %rcx
cmoveq %rax, %rcx
movq -0x50(%rbp), %r8
testq %r8, %r8
cmoveq %rax, %r8
leaq 0x2c188(%rip), %rsi     # 0x460b4
jmp 0x19ff8
movl %ebx, %edi
callq 0x2a444
testb %al, %al
je 0x1a0a7
movq -0x60(%rbp), %rdx
testq %rdx, %rdx
leaq 0x28fb8(%rip), %rax     # 0x42f06
cmoveq %rax, %rdx
movq -0x38(%rbp), %rcx
movq 0x28(%rcx), %rcx
testq %rcx, %rcx
cmoveq %rax, %rcx
movq -0x50(%rbp), %r8
testq %r8, %r8
cmoveq %rax, %r8
leaq 0x2c199(%rip), %rsi     # 0x4610c
jmp 0x19ff8
cmpb $0x10, -0x29(%rbp)
je 0x19fc5
cmpl $0xb, %ebx
movq -0x40(%rbp), %r15
je 0x19f90
cmpl $0xa, %ebx
jne 0x1a324
movq -0x60(%rbp), %rdx
testq %rdx, %rdx
leaq 0x28f68(%rip), %rax     # 0x42f06
cmoveq %rax, %rdx
movq -0x38(%rbp), %rcx
movq 0x28(%rcx), %rcx
testq %rcx, %rcx
cmoveq %rax, %rcx
movq -0x50(%rbp), %r8
testq %r8, %r8
cmoveq %rax, %r8
leaq 0x2c0db(%rip), %rsi     # 0x4609e
jmp 0x19ffc
movq -0x60(%rbp), %rdx
testq %rdx, %rdx
leaq 0x28f33(%rip), %rax     # 0x42f06
cmoveq %rax, %rdx
movq -0x38(%rbp), %rcx
movq 0x28(%rcx), %rcx
testq %rcx, %rcx
cmoveq %rax, %rcx
movq -0x50(%rbp), %r8
testq %r8, %r8
cmoveq %rax, %r8
leaq 0x2c07a(%rip), %rsi     # 0x46072
movq -0x40(%rbp), %r15
movq %r15, %rdi
xorl %eax, %eax
callq 0x7945
leaq -0x58(%rbp), %rbx
movq 0x8(%rbx), %rsi
testq %rsi, %rsi
leaq 0x28eee(%rip), %rax     # 0x42f06
cmoveq %rax, %rsi
leaq -0x68(%rbp), %r14
movq 0x8(%r14), %rdx
testq %rdx, %rdx
cmoveq %rax, %rdx
movq %r15, %rdi
callq 0x1def5
movq %r14, %rdi
callq 0x7852
movq %rbx, %rdi
callq 0x7852
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %ebx, %edi
callq 0x2a454
testb %al, %al
movq -0x40(%rbp), %r15
jne 0x1a0f9
cmpb $0xa, -0x29(%rbp)
jne 0x1a26f
movq -0x60(%rbp), %rdx
testq %rdx, %rdx
leaq 0x28e89(%rip), %rax     # 0x42f06
cmoveq %rax, %rdx
movq -0x38(%rbp), %rcx
movq 0x28(%rcx), %rcx
testq %rcx, %rcx
cmoveq %rax, %rcx
movq -0x50(%rbp), %r8
testq %r8, %r8
cmoveq %rax, %r8
leaq 0x2c053(%rip), %rsi     # 0x460f5
jmp 0x19ffc
movl %ebx, %edi
callq 0x2a454
testb %al, %al
movq -0x40(%rbp), %r15
je 0x1a131
movq -0x60(%rbp), %rdx
testq %rdx, %rdx
leaq 0x28e42(%rip), %rax     # 0x42f06
cmoveq %rax, %rdx
movq -0x38(%rbp), %rcx
movq 0x28(%rcx), %rcx
testq %rcx, %rcx
cmoveq %rax, %rcx
movq -0x50(%rbp), %r8
testq %r8, %r8
cmoveq %rax, %r8
leaq 0x2c023(%rip), %rsi     # 0x4610c
jmp 0x19ffc
movl %ebx, %edi
callq 0x2a454
testb %al, %al
je 0x1a173
movq -0x60(%rbp), %rdx
testq %rdx, %rdx
leaq 0x28dff(%rip), %rax     # 0x42f06
cmoveq %rax, %rdx
movq -0x38(%rbp), %rcx
movq 0x28(%rcx), %rcx
testq %rcx, %rcx
cmoveq %rax, %rcx
movq -0x50(%rbp), %r8
testq %r8, %r8
cmoveq %rax, %r8
leaq 0x2bf9e(%rip), %rsi     # 0x460ca
jmp 0x19ffc
cmpb $0x10, -0x29(%rbp)
jne 0x1a2a1
movq -0x60(%rbp), %rdx
testq %rdx, %rdx
leaq 0x28dbd(%rip), %rax     # 0x42f06
cmoveq %rax, %rdx
movq -0x38(%rbp), %rcx
movq 0x28(%rcx), %rcx
testq %rcx, %rcx
cmoveq %rax, %rcx
movq -0x50(%rbp), %r8
testq %r8, %r8
cmoveq %rax, %r8
leaq 0x2bfb6(%rip), %rsi     # 0x46124
jmp 0x19ffc
cmpb $0xb, -0x29(%rbp)
jne 0x1a2d3
movq -0x60(%rbp), %rdx
testq %rdx, %rdx
leaq 0x28d7b(%rip), %rax     # 0x42f06
cmoveq %rax, %rdx
movq -0x38(%rbp), %rcx
movq 0x28(%rcx), %rcx
testq %rcx, %rcx
cmoveq %rax, %rcx
movq -0x50(%rbp), %r8
testq %r8, %r8
cmoveq %rax, %r8
leaq 0x2bf30(%rip), %rsi     # 0x460e0
jmp 0x19ffc
leaq 0x28bed(%rip), %rdi     # 0x42da9
leaq 0x2a781(%rip), %rsi     # 0x44944
leaq 0x2bdf6(%rip), %rcx     # 0x45fc0
movl $0x177, %edx            # imm = 0x177
callq 0x30a0
leaq 0x28bdc(%rip), %rdi     # 0x42db7
leaq 0x2a762(%rip), %rsi     # 0x44944
leaq 0x2bdd7(%rip), %rcx     # 0x45fc0
movl $0x178, %edx            # imm = 0x178
callq 0x30a0
leaq 0x28bce(%rip), %rdi     # 0x42dc8
leaq 0x2a743(%rip), %rsi     # 0x44944
leaq 0x2bdb8(%rip), %rcx     # 0x45fc0
movl $0x179, %edx            # imm = 0x179
callq 0x30a0
leaq 0x28bbd(%rip), %rdi     # 0x42dd6
leaq 0x2a724(%rip), %rsi     # 0x44944
leaq 0x2bd99(%rip), %rcx     # 0x45fc0
movl $0x17a, %edx            # imm = 0x17A
callq 0x30a0
leaq 0x28d2f(%rip), %rdi     # 0x42f67
leaq 0x2a705(%rip), %rsi     # 0x44944
leaq 0x2bd7a(%rip), %rcx     # 0x45fc0
movl $0x18a, %edx            # imm = 0x18A
callq 0x30a0
leaq 0x25109(%rip), %rdi     # 0x3f360
leaq 0x2a6e6(%rip), %rsi     # 0x44944
leaq 0x2bd5b(%rip), %rcx     # 0x45fc0
movl $0x216, %edx            # imm = 0x216
callq 0x30a0
cmpl $0xb, %ebx
je 0x1a343
cmpl $0x10, -0x48(%rbp)
jne 0x1a362
leaq 0x250d7(%rip), %rdi     # 0x3f360
leaq 0x2a6b4(%rip), %rsi     # 0x44944
leaq 0x2bd29(%rip), %rcx     # 0x45fc0
movl $0x1fe, %edx            # imm = 0x1FE
callq 0x30a0
cmpl $0xb, %ebx
je 0x1a381
cmpl $0xa, -0x48(%rbp)
jne 0x1a3a0
leaq 0x250a5(%rip), %rdi     # 0x3f360
leaq 0x2a682(%rip), %rsi     # 0x44944
leaq 0x2bcf7(%rip), %rcx     # 0x45fc0
movl $0x20b, %edx            # imm = 0x20B
callq 0x30a0
cmpl $0x10, %ebx
je 0x1a3bf
cmpl $0xa, -0x48(%rbp)
jne 0x1a3de
leaq 0x25073(%rip), %rdi     # 0x3f360
leaq 0x2a650(%rip), %rsi     # 0x44944
leaq 0x2bcc5(%rip), %rcx     # 0x45fc0
movl $0x1e5, %edx            # imm = 0x1E5
callq 0x30a0
leaq 0x25054(%rip), %rdi     # 0x3f360
leaq 0x2a631(%rip), %rsi     # 0x44944
leaq 0x2bca6(%rip), %rcx     # 0x45fc0
movl $0x1bd, %edx            # imm = 0x1BD
callq 0x30a0
leaq 0x25035(%rip), %rdi     # 0x3f360
leaq 0x2a612(%rip), %rsi     # 0x44944
leaq 0x2bc87(%rip), %rcx     # 0x45fc0
movl $0x1da, %edx            # imm = 0x1DA
callq 0x30a0
leaq 0x25016(%rip), %rdi     # 0x3f360
leaq 0x2a5f3(%rip), %rsi     # 0x44944
leaq 0x2bc68(%rip), %rcx     # 0x45fc0
movl $0x1fb, %edx            # imm = 0x1FB
callq 0x30a0
leaq 0x24ff7(%rip), %rdi     # 0x3f360
leaq 0x2a5d4(%rip), %rsi     # 0x44944
leaq 0x2bc49(%rip), %rcx     # 0x45fc0
movl $0x200, %edx            # imm = 0x200
callq 0x30a0
leaq 0x24fd8(%rip), %rdi     # 0x3f360
leaq 0x2a5b5(%rip), %rsi     # 0x44944
leaq 0x2bc2a(%rip), %rcx     # 0x45fc0
movl $0x20e, %edx            # imm = 0x20E
callq 0x30a0
leaq 0x24fb9(%rip), %rdi     # 0x3f360
leaq 0x2a596(%rip), %rsi     # 0x44944
leaq 0x2bc0b(%rip), %rcx     # 0x45fc0
movl $0x213, %edx            # imm = 0x213
callq 0x30a0
leaq 0x24f9a(%rip), %rdi     # 0x3f360
leaq 0x2a577(%rip), %rsi     # 0x44944
leaq 0x2bbec(%rip), %rcx     # 0x45fc0
movl $0x1eb, %edx            # imm = 0x1EB
callq 0x30a0
leaq 0x24f7b(%rip), %rdi     # 0x3f360
leaq 0x2a558(%rip), %rsi     # 0x44944
leaq 0x2bbcd(%rip), %rcx     # 0x45fc0
movl $0x1ed, %edx            # imm = 0x1ED
callq 0x30a0