// File: /workspace/github_c_makefile_star2_O1/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, %r15
movq %rsi, %r12
movq %rdi, %rbx
callq 0x7da2
movl $0x1, %r14d
testl %eax, %eax
jne 0x5e8e
movl (%r12), %eax
cmpl $0x8, %eax
ja 0x5dee
movl $0x111, %ecx            # imm = 0x111
btl %eax, %ecx
jae 0x5dee
movl (%r15), %eax
cmpl $0x8, %eax
ja 0x5dee
btl %eax, %ecx
jb 0x5e8e
leaq -0x78(%rbp), %rax
movl $0xa, %ecx
movq %rax, %rdi
movq %r12, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0xc8(%rbp), %rdx
movl $0xa, %ecx
movq %rdx, %rdi
movq %r15, %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 0x5e45
movq -0x70(%rbp), %rax
cmpl $0x7, (%rax)
je 0x5e8e
movq -0xc0(%rbp), %rax
xorl %r14d, %r14d
cmpl $0x7, (%rax)
sete %r14b
jmp 0x5e8e
movl %ecx, %edi
xorl $0x2, %edi
orl %edi, %esi
jne 0x5e6f
leaq -0x118(%rbp), %rdx
movl $0xa, %ecx
movq %rdx, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl $0x1, (%rdx)
leaq -0x78(%rbp), %rsi
jmp 0x5e83
movl %eax, %esi
xorl $0x2, %esi
orl %edx, %esi
jne 0x5ea3
leaq -0xc8(%rbp), %rsi
leaq -0x78(%rbp), %rdx
movq %rbx, %rdi
callq 0x5d9a
movl %eax, %r14d
movl %r14d, %eax
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl $0x3, %eax
xorl $0x3, %ecx
xorl %r14d, %r14d
orl %eax, %ecx
jne 0x5e8e
movq -0x70(%rbp), %rsi
movq -0xc0(%rbp), %rdx
movq %rbx, %rdi
callq 0x7da2
testl %eax, %eax
je 0x5e8e
movl -0x50(%rbp), %eax
testl %eax, %eax
sete %dl
movl -0xa0(%rbp), %ecx
testl %ecx, %ecx
sete %sil
orb %dl, %sil
movl $0x1, %r14d
jne 0x5e8e
cmpl $0x2, %eax
sete %al
cmpl $0x2, %ecx
sete %cl
orb %al, %cl
jne 0x5e8e
movl -0x60(%rbp), %r15d
movl $0x0, %r14d
cmpl -0xb0(%rbp), %r15d
jne 0x5e8e
testl %r15d, %r15d
setle %r13b
jle 0x5f5c
movq -0x58(%rbp), %r14
movq -0xa8(%rbp), %r12
movq (%r14), %rsi
movq (%r12), %rdx
movq %rbx, %rdi
callq 0x7da2
testl %eax, %eax
je 0x5f5c
movl $0x1, %ecx
movq %rcx, %r13
cmpq %rcx, %r15
je 0x5f55
movq (%r14,%r13,8), %rsi
movq (%r12,%r13,8), %rdx
movq %rbx, %rdi
callq 0x7da2
leaq 0x1(%r13), %rcx
testl %eax, %eax
jne 0x5f35
cmpq %r15, %r13
setae %r13b
movzbl %r13b, %r14d
jmp 0x5e8e