// File: /workspace/github_c_makefile_star2_O1/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 0x1d1cc
movq %rsi, %r12
movl $0xf0003, %esi          # imm = 0xF0003
btl %edi, %esi
jae 0x1d1cc
cmpl $0x2, 0x44(%rcx)
jne 0x1d1de
movq 0x40(%r13), %rsi
testq %rsi, %rsi
je 0x1d1fd
movq 0x48(%rcx), %rax
movq 0x68(%rcx), %rdi
movq %rdi, -0x48(%rbp)
movq (%rax), %r14
movq 0x8(%rax), %r9
movq 0x68(%r14), %rbx
movq 0x68(%r9), %r8
movb 0x60(%r14), %al
cmpb $0x10, %al
movq %rdx, -0x40(%rbp)
movq %rcx, -0x68(%rbp)
movq %rsi, -0x60(%rbp)
movq %r8, -0x58(%rbp)
movq %rbx, -0x38(%rbp)
movq %r9, -0x50(%rbp)
je 0x1cd79
movb 0x60(%r9), %r15b
cmpb $0x10, %r15b
jne 0x1cd4e
movb %r15b, -0x2c(%rbp)
movq %r8, %rbx
jmp 0x1cd7c
movzbl %al, %edi
movq %r8, %rbx
callq 0x2acb1
movl %eax, -0x2c(%rbp)
movzbl %r15b, %edi
callq 0x2acb1
cmpl %eax, -0x2c(%rbp)
cmovgq -0x38(%rbp), %rbx
movq (%r13), %rdi
movq %rbx, %rsi
callq 0x2b043
movb %al, -0x2c(%rbp)
leaq -0x98(%rbp), %r15
movq %r15, %rdi
callq 0x7548
movq %r15, %rdi
movq -0x48(%rbp), %rsi
callq 0x198ea
leaq -0x298(%rbp), %r15
movq %r15, %rdi
callq 0x19eca
leaq -0x218(%rbp), %rdi
callq 0x19eca
leaq -0x198(%rbp), %rdi
callq 0x19eca
leaq -0x118(%rbp), %rdi
callq 0x19eca
movq %r13, %rdi
movq %r12, %rsi
movq %r15, %rdx
movq %r14, %rcx
callq 0x1ad56
leaq -0x288(%rbp), %rsi
movq %r12, %rdi
callq 0x788c
movq %r12, %rdi
movq %r15, %rsi
callq 0x788c
movq %r13, %rdi
movq %r12, %rsi
leaq -0x218(%rbp), %r14
movq %r14, %rdx
movq -0x50(%rbp), %rcx
callq 0x1ad56
leaq -0x208(%rbp), %rsi
movq %r12, %rdi
callq 0x788c
movq %r12, %rdi
movq %r14, %rsi
callq 0x788c
movq %r13, %rdi
leaq -0x198(%rbp), %r14
movq %r14, %rsi
movq %rbx, %rdx
movq %r15, %rcx
movq -0x38(%rbp), %r8
callq 0x19f71
leaq -0x188(%rbp), %rsi
movq %r12, %rdi
callq 0x788c
movq %r12, %rdi
movq %r14, %rsi
callq 0x788c
movq %r13, %rdi
leaq -0x118(%rbp), %r14
movq %r14, %rsi
movq %rbx, %rdx
leaq -0x218(%rbp), %rcx
movq -0x58(%rbp), %r8
callq 0x19f71
leaq -0x108(%rbp), %rsi
movq %r12, %rdi
callq 0x788c
movq %r12, %rdi
movq %r14, %rsi
callq 0x788c
leaq -0x88(%rbp), %rbx
movq %rbx, %rdi
callq 0x7548
movq -0x60(%rbp), %r15
movl 0x54(%r15), %edx
leal 0x1(%rdx), %eax
movl %eax, 0x54(%r15)
leaq 0x291dd(%rip), %r14     # 0x4609a
movq %rbx, %rdi
movq %r14, %rsi
xorl %eax, %eax
callq 0x7b31
leaq -0x78(%rbp), %rbx
movq %rbx, %rdi
callq 0x7548
movl 0x54(%r15), %edx
leal 0x1(%rdx), %eax
movl %eax, 0x54(%r15)
movq %rbx, %rdi
movq %r14, %rsi
xorl %eax, %eax
callq 0x7b31
movq -0x68(%rbp), %rax
movl (%rax), %eax
leal -0xe80(%rax), %ecx
cmpl $0x3, %ecx
ja 0x1cf2e
leaq 0x28932(%rip), %rax     # 0x45838
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movzbl -0x2c(%rbp), %ebx
movl %ebx, %edi
callq 0x2ad2f
testb %al, %al
je 0x1d053
leaq 0x29ac2(%rip), %rbx     # 0x469eb
jmp 0x1d0d9
cmpl $0xe70, %eax            # imm = 0xE70
je 0x1cfa7
cmpl $0xe71, %eax            # imm = 0xE71
jne 0x1d21c
movzbl -0x2c(%rbp), %r14d
movl %r14d, %edi
callq 0x2ad50
leaq 0x29bca(%rip), %rbx     # 0x46b1e
testb %al, %al
jne 0x1d0d9
movl %r14d, %edi
callq 0x2ad81
testb %al, %al
jne 0x1d0d9
movl %r14d, %edi
callq 0x2ad60
testb %al, %al
je 0x1d279
leaq 0x29bb0(%rip), %rbx     # 0x46b33
jmp 0x1d0d9
movzbl -0x2c(%rbp), %ebx
movl %ebx, %edi
callq 0x2ad2f
testb %al, %al
je 0x1d025
leaq 0x29acd(%rip), %rbx     # 0x46a6f
jmp 0x1d0d9
movzbl -0x2c(%rbp), %r14d
movl %r14d, %edi
callq 0x2ad50
leaq 0x29b38(%rip), %rbx     # 0x46af3
testb %al, %al
jne 0x1d0d9
movl %r14d, %edi
callq 0x2ad81
testb %al, %al
jne 0x1d0d9
movl %r14d, %edi
callq 0x2ad60
testb %al, %al
je 0x1d23b
leaq 0x29b1e(%rip), %rbx     # 0x46b08
jmp 0x1d0d9
movzbl -0x2c(%rbp), %ebx
movl %ebx, %edi
callq 0x2ad2f
testb %al, %al
je 0x1d03c
leaq 0x29aac(%rip), %rbx     # 0x46ab1
jmp 0x1d0d9
movzbl -0x2c(%rbp), %ebx
movl %ebx, %edi
callq 0x2ad2f
testb %al, %al
je 0x1d067
leaq 0x29a0d(%rip), %rbx     # 0x46a2d
jmp 0x1d0d9
movl %ebx, %edi
callq 0x2ad3f
testb %al, %al
je 0x1d07b
leaq 0x29a4e(%rip), %rbx     # 0x46a85
jmp 0x1d0d9
movl %ebx, %edi
callq 0x2ad3f
testb %al, %al
je 0x1d093
leaq 0x29a79(%rip), %rbx     # 0x46ac7
jmp 0x1d0d9
movl %ebx, %edi
callq 0x2ad3f
testb %al, %al
je 0x1d0ab
leaq 0x2999c(%rip), %rbx     # 0x46a01
jmp 0x1d0d9
movl %ebx, %edi
callq 0x2ad3f
testb %al, %al
je 0x1d0c3
leaq 0x299ca(%rip), %rbx     # 0x46a43
jmp 0x1d0d9
movl %ebx, %edi
callq 0x2ad60
testb %al, %al
je 0x1d25a
leaq 0x29a0a(%rip), %rbx     # 0x46a9b
jmp 0x1d0d9
movl %ebx, %edi
callq 0x2ad60
testb %al, %al
je 0x1d298
leaq 0x29a34(%rip), %rbx     # 0x46add
jmp 0x1d0d9
movl %ebx, %edi
callq 0x2ad60
testb %al, %al
je 0x1d2b7
leaq 0x29956(%rip), %rbx     # 0x46a17
jmp 0x1d0d9
movl %ebx, %edi
callq 0x2ad60
testb %al, %al
je 0x1d2d6
leaq 0x29980(%rip), %rbx     # 0x46a59
leaq -0x88(%rbp), %r14
movq 0x8(%r14), %rdx
testq %rdx, %rdx
leaq 0x26dcc(%rip), %r15     # 0x43eba
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 -0x40(%rbp), %r12
movq %r12, %rdi
movq %rbx, %rsi
xorl %eax, %eax
callq 0x7b31
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 0x29179(%rip), %rsi     # 0x462d3
movq %r12, %rdi
xorl %eax, %eax
callq 0x7b31
movq 0x8(%r13), %rsi
testq %rsi, %rsi
cmoveq %r15, %rsi
movq 0x8(%rbx), %rdx
testq %rdx, %rdx
cmoveq %r15, %rdx
movq %r12, %rdi
callq 0x1e280
movq %r13, %rdi
callq 0x7a38
leaq -0x298(%rbp), %rdi
callq 0x1a7ab
leaq -0x218(%rbp), %rdi
callq 0x1a7ab
leaq -0x198(%rbp), %rdi
callq 0x1a7ab
leaq -0x118(%rbp), %rdi
callq 0x1a7ab
movq %r14, %rdi
callq 0x7a38
movq %rbx, %rdi
callq 0x7a38
movb $0x1, %al
addq $0x278, %rsp            # imm = 0x278
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2ea70(%rip), %rdi     # 0x4bc55
leaq 0x28688(%rip), %rsi     # 0x45874
leaq 0x2978f(%rip), %rcx     # 0x46982
movl $0xf09, %edx            # imm = 0xF09
callq 0x30a0
leaq 0x26d17(%rip), %rdi     # 0x43f1b
leaq 0x28669(%rip), %rsi     # 0x45874
leaq 0x29770(%rip), %rcx     # 0x46982
movl $0xf0c, %edx            # imm = 0xF0C
callq 0x30a0
leaq 0x23161(%rip), %rdi     # 0x40384
leaq 0x2864a(%rip), %rsi     # 0x45874
leaq 0x29751(%rip), %rcx     # 0x46982
movl $0xfb0, %edx            # imm = 0xFB0
callq 0x30a0
leaq 0x23142(%rip), %rdi     # 0x40384
leaq 0x2862b(%rip), %rsi     # 0x45874
leaq 0x29732(%rip), %rcx     # 0x46982
movl $0xfa0, %edx            # imm = 0xFA0
callq 0x30a0
leaq 0x23123(%rip), %rdi     # 0x40384
leaq 0x2860c(%rip), %rsi     # 0x45874
leaq 0x29713(%rip), %rcx     # 0x46982
movl $0xf89, %edx            # imm = 0xF89
callq 0x30a0
leaq 0x23104(%rip), %rdi     # 0x40384
leaq 0x285ed(%rip), %rsi     # 0x45874
leaq 0x296f4(%rip), %rcx     # 0x46982
movl $0xfab, %edx            # imm = 0xFAB
callq 0x30a0
leaq 0x230e5(%rip), %rdi     # 0x40384
leaq 0x285ce(%rip), %rsi     # 0x45874
leaq 0x296d5(%rip), %rcx     # 0x46982
movl $0xf95, %edx            # imm = 0xF95
callq 0x30a0
leaq 0x230c6(%rip), %rdi     # 0x40384
leaq 0x285af(%rip), %rsi     # 0x45874
leaq 0x296b6(%rip), %rcx     # 0x46982
movl $0xf71, %edx            # imm = 0xF71
callq 0x30a0
leaq 0x230a7(%rip), %rdi     # 0x40384
leaq 0x28590(%rip), %rsi     # 0x45874
leaq 0x29697(%rip), %rcx     # 0x46982
movl $0xf7d, %edx            # imm = 0xF7D
callq 0x30a0