// File: /workspace/github_c_makefile_star2_O3/Ihsoh[P]ilang/compiler/frontend/irgen_llvmir.c
// Function: ir_expr_comparison
static bool _ir_expr_comparison(
	IRGeneratorLlvmirContext *ctx,
	ResizableString *rstr,
	_ExprResult *expr_result,
	ParserASTNode *node
) {
	assert(ctx);
	assert(rstr);
	assert(expr_result);
	assert(node);

	switch (node->type) {
		case FE_NODE_EXPR_LT:
		case FE_NODE_EXPR_LE:
		case FE_NODE_EXPR_GT:
		case FE_NODE_EXPR_GE:
		case FE_NODE_EXPR_EQ:
		case FE_NODE_EXPR_NEQ: {
			assert(node->nchilds == 2);

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

			ParserASTNode *node_lhs = node->childs[0];
			ParserASTNode *node_rhs = node->childs[1];

			ParserASTNode *node_type = FE_EXPR_AST_NODE_GET_TYPE_NODE(node);

			ParserASTNode *node_lhs_type = FE_EXPR_AST_NODE_GET_TYPE_NODE(node_lhs);
			ParserASTNode *node_rhs_type = FE_EXPR_AST_NODE_GET_TYPE_NODE(node_rhs);
			
			uint8_t lhs_type = FE_EXPR_AST_NODE_GET_TYPE(node_lhs);
			uint8_t rhs_type = FE_EXPR_AST_NODE_GET_TYPE(node_rhs);
			
			ParserASTNode *node_target_type = NULL;
			uint8_t target_type;
			if (lhs_type == FE_TYPE_POINTER) {
				node_target_type = node_lhs_type;
				target_type = lhs_type;
			} else if (rhs_type == FE_TYPE_POINTER) {
				node_target_type = node_rhs_type;
				target_type = rhs_type;
			} else {
				int32_t lhs_type_weight = fe_sem_get_primitive_type_weight(lhs_type);
				int32_t rhs_type_weight = fe_sem_get_primitive_type_weight(rhs_type); 
				if (lhs_type_weight > rhs_type_weight) {
					node_target_type = node_lhs_type;
				} else {
					node_target_type = node_rhs_type;
				}
				target_type = fe_sem_get_type_by_type_node(ctx->psrctx, node_target_type);
			}

			ResizableString rstr_type;
			rstr_init(&rstr_type);

			_ir_type(ctx, &rstr_type, node_type);

			_ExprResult result_lhs;
			_ExprResult result_rhs;
			_ExprResult result_lhs_casted;
			_ExprResult result_rhs_casted;

			_expr_result_init(&result_lhs);
			_expr_result_init(&result_rhs);
			_expr_result_init(&result_lhs_casted);
			_expr_result_init(&result_rhs_casted);

			_ir_expr(ctx, rstr, &result_lhs, node_lhs);
			rstr_append_with_rstr(rstr, &(result_lhs.rstr_for_result_ptr));
			rstr_append_with_rstr(rstr, &(result_lhs.rstr_for_result));

			_ir_expr(ctx, rstr, &result_rhs, node_rhs);
			rstr_append_with_rstr(rstr, &(result_rhs.rstr_for_result_ptr));
			rstr_append_with_rstr(rstr, &(result_rhs.rstr_for_result));

			_expr_result_cast(
				ctx,
				&result_lhs_casted,
				node_target_type,
				&result_lhs,
				node_lhs_type
			);
			rstr_append_with_rstr(rstr, &(result_lhs_casted.rstr_for_result_ptr));
			rstr_append_with_rstr(rstr, &(result_lhs_casted.rstr_for_result));

			_expr_result_cast(
				ctx,
				&result_rhs_casted,
				node_target_type,
				&result_rhs,
				node_rhs_type
			);
			rstr_append_with_rstr(rstr, &(result_rhs_casted.rstr_for_result_ptr));
			rstr_append_with_rstr(rstr, &(result_rhs_casted.rstr_for_result));

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

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

			#define	_A(cmd)	\
				rstr_appendf(	\
					&(expr_result->rstr_for_result),	\
					"%s = "cmd" %s, %s\n",	\
					RSTR_CSTR(&rstr_tmp_label_val),	\
					RSTR_CSTR(&(result_lhs_casted.rstr_result)),	\
					RSTR_CSTR(&(result_rhs_casted.rstr_result_val))	\
				);

			switch (node->type) {
				case FE_NODE_EXPR_LT: {
					if (fe_sem_is_signed_type(target_type)) {
						_A("icmp slt")
					} else if (fe_sem_is_unsigned_type(target_type)) {
						_A("icmp ult")
					} else if (fe_sem_is_float_type(target_type)) {
						_A("fcmp olt")
					} else {
						assert(0);
					}
					break;
				}
				case FE_NODE_EXPR_LE: {
					if (fe_sem_is_signed_type(target_type)) {
						_A("icmp sle")
					} else if (fe_sem_is_unsigned_type(target_type)) {
						_A("icmp ule")
					} else if (fe_sem_is_float_type(target_type)) {
						_A("fcmp ole")
					} else {
						assert(0);
					}
					break;
				}
				case FE_NODE_EXPR_GT: {
					if (fe_sem_is_signed_type(target_type)) {
						_A("icmp sgt")
					} else if (fe_sem_is_unsigned_type(target_type)) {
						_A("icmp ugt")
					} else if (fe_sem_is_float_type(target_type)) {
						_A("fcmp ogt")
					} else {
						assert(0);
					}
					break;
				}
				case FE_NODE_EXPR_GE: {
					if (fe_sem_is_signed_type(target_type)) {
						_A("icmp sge")
					} else if (fe_sem_is_unsigned_type(target_type)) {
						_A("icmp uge")
					} else if (fe_sem_is_float_type(target_type)) {
						_A("fcmp oge")
					} else {
						assert(0);
					}
					break;
				}
				case FE_NODE_EXPR_EQ: {
					if (fe_sem_is_integer_type(target_type)
							|| fe_sem_is_pointer_type(target_type)) {
						_A("icmp eq")
					} else if (fe_sem_is_float_type(target_type)) {
						_A("fcmp oeq")
					} else {
						assert(0);
					}
					break;
				}
				case FE_NODE_EXPR_NEQ: {
					if (fe_sem_is_integer_type(target_type)
							|| fe_sem_is_pointer_type(target_type)) {
						_A("icmp ne")
					} else if (fe_sem_is_float_type(target_type)) {
						_A("fcmp one")
					} else {
						assert(0);
					}
					break;
				}
				default: {
					assert(0);
					break;
				}
			}

			#undef	_A

			rstr_appendf(
				&(expr_result->rstr_for_result),
				"%s = zext i1 %s to %s\n",
				RSTR_CSTR(&rstr_tmp_label_val1),
				RSTR_CSTR(&rstr_tmp_label_val),
				RSTR_CSTR(&rstr_type)
			);
			_expr_result_set_result(
				expr_result,
				RSTR_CSTR(&rstr_type),
				RSTR_CSTR(&rstr_tmp_label_val1)
			);

			rstr_free(&rstr_type);
			_expr_result_free(&result_lhs);
			_expr_result_free(&result_rhs);
			_expr_result_free(&result_lhs_casted);
			_expr_result_free(&result_rhs_casted);
			rstr_free(&rstr_tmp_label_val);
			rstr_free(&rstr_tmp_label_val1);

			return true;
		}
		default: {
			return false;
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x278, %rsp            # imm = 0x278
movq %rdi, %r13
xorl %eax, %eax
movl $0xfffff190, %edi       # imm = 0xFFFFF190
addl (%rcx), %edi
cmpl $0x13, %edi
ja 0x1ce41
movq %rsi, %r12
movl $0xf0003, %esi          # imm = 0xF0003
btl %edi, %esi
jae 0x1ce41
cmpl $0x2, 0x44(%rcx)
jne 0x1ce53
movq 0x40(%r13), %rsi
testq %rsi, %rsi
je 0x1ce72
movq %rdx, -0x48(%rbp)
movq 0x48(%rcx), %rax
movq 0x68(%rcx), %rdx
movq %rdx, -0x50(%rbp)
movq (%rax), %r14
movq 0x8(%rax), %r9
movq 0x68(%r14), %r8
movq 0x68(%r9), %rdi
movb 0x60(%r14), %dl
movb $0x10, %al
cmpb $0x10, %dl
movq %rcx, -0x68(%rbp)
movq %rsi, -0x60(%rbp)
movq %rdi, -0x40(%rbp)
movq %r8, -0x38(%rbp)
movq %r9, -0x58(%rbp)
jne 0x1c9b7
movq %r8, %rbx
jmp 0x1c9ee
movb 0x60(%r9), %r15b
movq %rdi, %rbx
cmpb $0x10, %r15b
je 0x1c9ee
movzbl %dl, %edi
callq 0x2a3c6
movl %eax, %ebx
movzbl %r15b, %edi
callq 0x2a3c6
cmpl %eax, %ebx
movq -0x40(%rbp), %rbx
cmovgq -0x38(%rbp), %rbx
movq (%r13), %rdi
movq %rbx, %rsi
callq 0x2a70b
movb %al, -0x29(%rbp)
leaq -0x98(%rbp), %r15
movq %r15, %rdi
callq 0x7354
movq %r15, %rdi
movq -0x50(%rbp), %rsi
callq 0x19540
leaq -0x298(%rbp), %r15
movq %r15, %rdi
callq 0x19b1c
leaq -0x218(%rbp), %rdi
callq 0x19b1c
leaq -0x198(%rbp), %rdi
callq 0x19b1c
leaq -0x118(%rbp), %rdi
callq 0x19b1c
movq %r13, %rdi
movq %r12, %rsi
movq %r15, %rdx
movq %r14, %rcx
callq 0x1a9a8
leaq -0x288(%rbp), %rsi
movq %r12, %rdi
callq 0x769e
movq %r12, %rdi
movq %r15, %rsi
callq 0x769e
movq %r13, %rdi
movq %r12, %rsi
leaq -0x218(%rbp), %r14
movq %r14, %rdx
movq -0x58(%rbp), %rcx
callq 0x1a9a8
leaq -0x208(%rbp), %rsi
movq %r12, %rdi
callq 0x769e
movq %r12, %rdi
movq %r14, %rsi
callq 0x769e
movq %r13, %rdi
leaq -0x198(%rbp), %r14
movq %r14, %rsi
movq %rbx, %rdx
movq %r15, %rcx
movq -0x38(%rbp), %r8
callq 0x19bc3
leaq -0x188(%rbp), %rsi
movq %r12, %rdi
callq 0x769e
movq %r12, %rdi
movq %r14, %rsi
callq 0x769e
movq %r13, %rdi
leaq -0x118(%rbp), %r14
movq %r14, %rsi
movq %rbx, %rdx
leaq -0x218(%rbp), %rcx
movq -0x40(%rbp), %r8
callq 0x19bc3
leaq -0x108(%rbp), %rsi
movq %r12, %rdi
callq 0x769e
movq %r12, %rdi
movq %r14, %rsi
callq 0x769e
leaq -0x88(%rbp), %rbx
movq %rbx, %rdi
callq 0x7354
movq -0x60(%rbp), %r15
movl 0x54(%r15), %edx
leal 0x1(%rdx), %eax
movl %eax, 0x54(%r15)
leaq 0x28638(%rip), %r14     # 0x4516a
movq %rbx, %rdi
movq %r14, %rsi
xorl %eax, %eax
callq 0x7945
leaq -0x78(%rbp), %rbx
movq %rbx, %rdi
callq 0x7354
movl 0x54(%r15), %edx
leal 0x1(%rdx), %eax
movl %eax, 0x54(%r15)
movq %rbx, %rdi
movq %r14, %rsi
xorl %eax, %eax
callq 0x7945
movq -0x68(%rbp), %rax
movl (%rax), %eax
leal -0xe80(%rax), %ecx
cmpl $0x3, %ecx
ja 0x1cba5
leaq 0x27d8d(%rip), %rax     # 0x44908
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
movb -0x29(%rbp), %al
jmpq *%rcx
movzbl %al, %ebx
movl %ebx, %edi
callq 0x2a444
testb %al, %al
je 0x1ccc8
leaq 0x28f1b(%rip), %rbx     # 0x45abb
jmp 0x1cd4e
cmpl $0xe70, %eax            # imm = 0xE70
movb -0x29(%rbp), %cl
je 0x1cc1f
cmpl $0xe71, %eax            # imm = 0xE71
jne 0x1ce91
movzbl %cl, %r14d
movl %r14d, %edi
callq 0x2a465
leaq 0x29021(%rip), %rbx     # 0x45bee
testb %al, %al
jne 0x1cd4e
movl %r14d, %edi
callq 0x2a496
testb %al, %al
jne 0x1cd4e
movl %r14d, %edi
callq 0x2a475
testb %al, %al
je 0x1ceee
leaq 0x29007(%rip), %rbx     # 0x45c03
jmp 0x1cd4e
movzbl %al, %ebx
movl %ebx, %edi
callq 0x2a444
testb %al, %al
je 0x1cc9a
leaq 0x28f25(%rip), %rbx     # 0x45b3f
jmp 0x1cd4e
movzbl %cl, %r14d
movl %r14d, %edi
callq 0x2a465
leaq 0x28f91(%rip), %rbx     # 0x45bc3
testb %al, %al
jne 0x1cd4e
movl %r14d, %edi
callq 0x2a496
testb %al, %al
jne 0x1cd4e
movl %r14d, %edi
callq 0x2a475
testb %al, %al
je 0x1ceb0
leaq 0x28f77(%rip), %rbx     # 0x45bd8
jmp 0x1cd4e
movzbl %al, %ebx
movl %ebx, %edi
callq 0x2a444
testb %al, %al
je 0x1ccb1
leaq 0x28f06(%rip), %rbx     # 0x45b81
jmp 0x1cd4e
movzbl %al, %ebx
movl %ebx, %edi
callq 0x2a444
testb %al, %al
je 0x1ccdc
leaq 0x28e68(%rip), %rbx     # 0x45afd
jmp 0x1cd4e
movl %ebx, %edi
callq 0x2a454
testb %al, %al
je 0x1ccf0
leaq 0x28ea9(%rip), %rbx     # 0x45b55
jmp 0x1cd4e
movl %ebx, %edi
callq 0x2a454
testb %al, %al
je 0x1cd08
leaq 0x28ed4(%rip), %rbx     # 0x45b97
jmp 0x1cd4e
movl %ebx, %edi
callq 0x2a454
testb %al, %al
je 0x1cd20
leaq 0x28df7(%rip), %rbx     # 0x45ad1
jmp 0x1cd4e
movl %ebx, %edi
callq 0x2a454
testb %al, %al
je 0x1cd38
leaq 0x28e25(%rip), %rbx     # 0x45b13
jmp 0x1cd4e
movl %ebx, %edi
callq 0x2a475
testb %al, %al
je 0x1cecf
leaq 0x28e65(%rip), %rbx     # 0x45b6b
jmp 0x1cd4e
movl %ebx, %edi
callq 0x2a475
testb %al, %al
je 0x1cf0d
leaq 0x28e8f(%rip), %rbx     # 0x45bad
jmp 0x1cd4e
movl %ebx, %edi
callq 0x2a475
testb %al, %al
je 0x1cf2c
leaq 0x28db1(%rip), %rbx     # 0x45ae7
jmp 0x1cd4e
movl %ebx, %edi
callq 0x2a475
testb %al, %al
je 0x1cf4b
leaq 0x28ddb(%rip), %rbx     # 0x45b29
leaq -0x88(%rbp), %r14
movq 0x8(%r14), %rdx
testq %rdx, %rdx
leaq 0x261a3(%rip), %r15     # 0x42f06
cmoveq %r15, %rdx
leaq -0x198(%rbp), %rax
movq 0x28(%rax), %rcx
testq %rcx, %rcx
cmoveq %r15, %rcx
leaq -0x118(%rbp), %rax
movq 0x48(%rax), %r8
testq %r8, %r8
cmoveq %r15, %r8
movq -0x48(%rbp), %r12
movq %r12, %rdi
movq %rbx, %rsi
xorl %eax, %eax
callq 0x7945
leaq -0x78(%rbp), %rbx
movq 0x8(%rbx), %rdx
testq %rdx, %rdx
cmoveq %r15, %rdx
movq 0x8(%r14), %rcx
testq %rcx, %rcx
cmoveq %r15, %rcx
leaq -0x98(%rbp), %r13
movq 0x8(%r13), %r8
testq %r8, %r8
cmoveq %r15, %r8
leaq 0x285d4(%rip), %rsi     # 0x453a3
movq %r12, %rdi
xorl %eax, %eax
callq 0x7945
movq 0x8(%r13), %rsi
testq %rsi, %rsi
cmoveq %r15, %rsi
movq 0x8(%rbx), %rdx
testq %rdx, %rdx
cmoveq %r15, %rdx
movq %r12, %rdi
callq 0x1def5
movq %r13, %rdi
callq 0x7852
leaq -0x298(%rbp), %rdi
callq 0x1a3fd
leaq -0x218(%rbp), %rdi
callq 0x1a3fd
leaq -0x198(%rbp), %rdi
callq 0x1a3fd
leaq -0x118(%rbp), %rdi
callq 0x1a3fd
movq %r14, %rdi
callq 0x7852
movq %rbx, %rdi
callq 0x7852
movb $0x1, %al
addq $0x278, %rsp            # imm = 0x278
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2de9b(%rip), %rdi     # 0x4acf5
leaq 0x27ae3(%rip), %rsi     # 0x44944
leaq 0x28bea(%rip), %rcx     # 0x45a52
movl $0xf09, %edx            # imm = 0xF09
callq 0x30a0
leaq 0x260ee(%rip), %rdi     # 0x42f67
leaq 0x27ac4(%rip), %rsi     # 0x44944
leaq 0x28bcb(%rip), %rcx     # 0x45a52
movl $0xf0c, %edx            # imm = 0xF0C
callq 0x30a0
leaq 0x224c8(%rip), %rdi     # 0x3f360
leaq 0x27aa5(%rip), %rsi     # 0x44944
leaq 0x28bac(%rip), %rcx     # 0x45a52
movl $0xfb0, %edx            # imm = 0xFB0
callq 0x30a0
leaq 0x224a9(%rip), %rdi     # 0x3f360
leaq 0x27a86(%rip), %rsi     # 0x44944
leaq 0x28b8d(%rip), %rcx     # 0x45a52
movl $0xfa0, %edx            # imm = 0xFA0
callq 0x30a0
leaq 0x2248a(%rip), %rdi     # 0x3f360
leaq 0x27a67(%rip), %rsi     # 0x44944
leaq 0x28b6e(%rip), %rcx     # 0x45a52
movl $0xf89, %edx            # imm = 0xF89
callq 0x30a0
leaq 0x2246b(%rip), %rdi     # 0x3f360
leaq 0x27a48(%rip), %rsi     # 0x44944
leaq 0x28b4f(%rip), %rcx     # 0x45a52
movl $0xfab, %edx            # imm = 0xFAB
callq 0x30a0
leaq 0x2244c(%rip), %rdi     # 0x3f360
leaq 0x27a29(%rip), %rsi     # 0x44944
leaq 0x28b30(%rip), %rcx     # 0x45a52
movl $0xf95, %edx            # imm = 0xF95
callq 0x30a0
leaq 0x2242d(%rip), %rdi     # 0x3f360
leaq 0x27a0a(%rip), %rsi     # 0x44944
leaq 0x28b11(%rip), %rcx     # 0x45a52
movl $0xf71, %edx            # imm = 0xF71
callq 0x30a0
leaq 0x2240e(%rip), %rdi     # 0x3f360
leaq 0x279eb(%rip), %rsi     # 0x44944
leaq 0x28af2(%rip), %rcx     # 0x45a52
movl $0xf7d, %edx            # imm = 0xF7D
callq 0x30a0