// File: /workspace/github_c_makefile_star2_O3/hsjoihs[P]c-compiler/typecheck_expression.c
// Function: is_compatible
static int is_compatible(const struct AnalyzerState *ptr_ps,
                         const struct Type *ref_t1, const struct Type *ref_t2)
{
	if (is_strictly_equal(ptr_ps, ref_t1, ref_t2)) {
		return 1;
	}

	if (is_integral(ref_t1) && is_integral(ref_t2)) {
		return 1;
	}

	const struct Type t1 = *ref_t1;
	const struct Type t2 = *ref_t2;

	if (t1.type_category == PTR_ && t2.type_category == PTR_) {
		return t1.derived_from->type_category == VOID_ ||
		       t2.derived_from->type_category == VOID_;
	}

	if (t1.type_category == PTR_ && t2.type_category == ARRAY) {
		struct Type t3 = t2; /* copy of t2 */
		t3.type_category = PTR_;
		return is_compatible(ptr_ps, &t1, &t3);
	}

	if (t1.type_category == ARRAY && t2.type_category == PTR_) {
		return is_compatible(ptr_ps, &t2, &t1);
	}

	if (t1.type_category == FN && t2.type_category == FN) {
		if (!is_strictly_equal(ptr_ps, t1.derived_from, t2.derived_from)) {
			return 0;
		}

		if (t1.param_infos_validity == INVALID ||
		    t2.param_infos_validity == INVALID) {
			return 1;
		}

		if (t1.param_infos_validity == VA_ARGS ||
		    t2.param_infos_validity == VA_ARGS) {
#ifdef __STDC__
#warning should typecheck
#endif
			return 1;
		}

		if (t1.param_infos.length != t2.param_infos.length) {
			return 0;
		}

		for (int i = 0; i < t1.param_infos.length; i++) {
			const struct TypeAndIdent *ptr_ti1 = t1.param_infos.vector[i];
			const struct TypeAndIdent *ptr_ti2 = t2.param_infos.vector[i];

			if (!is_strictly_equal(ptr_ps, &ptr_ti1->type, &ptr_ti2->type)) {
				return 0;
			}
		}
		return 1;
	}

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xf8, %rsp
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %rbx
callq 0x7f53
movl %eax, %ecx
movl $0x1, %eax
testl %ecx, %ecx
jne 0x6053
movl (%r15), %ecx
cmpl $0x8, %ecx
ja 0x5fb3
movl $0x111, %edx            # imm = 0x111
btl %ecx, %edx
jae 0x5fb3
movl (%r14), %ecx
cmpl $0x8, %ecx
ja 0x5fb3
btl %ecx, %edx
jb 0x6053
leaq -0x78(%rbp), %rax
movl $0xa, %ecx
movq %rax, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0xc8(%rbp), %rdx
movl $0xa, %ecx
movq %rdx, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl (%rax), %eax
movl %eax, %esi
xorl $0x1, %esi
movl (%rdx), %ecx
movl %ecx, %edx
xorl $0x1, %edx
movl %esi, %edi
orl %edx, %edi
jne 0x600d
movq -0x70(%rbp), %rcx
movl $0x1, %eax
cmpl $0x7, (%rcx)
je 0x6053
movq -0xc0(%rbp), %rcx
xorl %eax, %eax
cmpl $0x7, (%rcx)
sete %al
jmp 0x6053
movl %ecx, %edi
xorl $0x2, %edi
orl %edi, %esi
jne 0x6037
leaq -0x118(%rbp), %rdx
movl $0xa, %ecx
movq %rdx, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl $0x1, (%rdx)
leaq -0x78(%rbp), %rsi
jmp 0x604b
movl %eax, %esi
xorl $0x2, %esi
orl %edx, %esi
jne 0x6065
leaq -0xc8(%rbp), %rsi
leaq -0x78(%rbp), %rdx
movq %rbx, %rdi
callq 0x5f5f
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl $0x3, %eax
xorl $0x3, %ecx
orl %eax, %ecx
jne 0x6129
movq -0x70(%rbp), %rsi
movq -0xc0(%rbp), %rdx
movq %rbx, %rdi
callq 0x7f53
testl %eax, %eax
je 0x6129
movl -0x50(%rbp), %ecx
testl %ecx, %ecx
sete %al
movl -0xa0(%rbp), %edx
testl %edx, %edx
sete %sil
orb %al, %sil
movl $0x1, %eax
jne 0x6053
cmpl $0x2, %ecx
sete %cl
cmpl $0x2, %edx
sete %dl
orb %cl, %dl
jne 0x6053
movl -0x60(%rbp), %r14d
cmpl -0xb0(%rbp), %r14d
jne 0x6129
testl %r14d, %r14d
jle 0x6053
movq -0x58(%rbp), %r15
movq -0xa8(%rbp), %r12
movq (%r15), %rsi
movq (%r12), %rdx
movq %rbx, %rdi
callq 0x7f53
movl %eax, %ecx
movl $0x0, %eax
testl %ecx, %ecx
je 0x6053
movl $0x1, %ecx
movq %rcx, %r13
cmpq %rcx, %r14
je 0x611c
movq (%r15,%r13,8), %rsi
movq (%r12,%r13,8), %rdx
movq %rbx, %rdi
callq 0x7f53
leaq 0x1(%r13), %rcx
testl %eax, %eax
jne 0x60fc
xorl %eax, %eax
cmpq %r14, %r13
setae %al
jmp 0x6053
xorl %eax, %eax
jmp 0x6053