// File: /workspace/github_c_makefile_star2_O2/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 0x6f09
pushq $0x1
popq %r14
testl %eax, %eax
je 0x4d5b
movl %r14d, %eax
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r12, %rdi
callq 0x4fc5
testl %eax, %eax
je 0x4d73
movq %r15, %rdi
callq 0x4fc5
testl %eax, %eax
jne 0x4d46
pushq $0xa
popq %rax
leaq -0x80(%rbp), %rdx
movq %rax, %rcx
movq %rdx, %rdi
movq %r12, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0xd0(%rbp), %r8
movq %rax, %rcx
movq %r8, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl (%rdx), %eax
movl %eax, %esi
xorl $0x1, %esi
movl (%r8), %ecx
movl %ecx, %edx
xorl $0x1, %edx
movl %esi, %edi
orl %edx, %edi
jne 0x4dcd
movq -0x78(%rbp), %rax
cmpl $0x7, (%rax)
je 0x4d46
movq -0xc8(%rbp), %rax
xorl %r14d, %r14d
cmpl $0x7, (%rax)
sete %r14b
jmp 0x4d46
movl %ecx, %edi
xorl $0x2, %edi
orl %edi, %esi
jne 0x4df5
pushq $0xa
popq %rcx
leaq -0x120(%rbp), %rdx
movq %rdx, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl $0x1, (%rdx)
leaq -0x80(%rbp), %rsi
jmp 0x4e09
movl %eax, %esi
xorl $0x2, %esi
orl %edx, %esi
jne 0x4e19
leaq -0xd0(%rbp), %rsi
leaq -0x80(%rbp), %rdx
movq %rbx, %rdi
callq 0x4d1c
movl %eax, %r14d
jmp 0x4d46
xorl $0x3, %eax
xorl $0x3, %ecx
xorl %r14d, %r14d
orl %eax, %ecx
jne 0x4d46
movq -0x78(%rbp), %rsi
movq -0xc8(%rbp), %rdx
movq %rbx, %rdi
callq 0x6f09
testl %eax, %eax
je 0x4d46
movl -0x58(%rbp), %eax
testl %eax, %eax
sete %dl
movl -0xa8(%rbp), %ecx
testl %ecx, %ecx
sete %sil
orb %dl, %sil
pushq $0x1
popq %r14
jne 0x4d46
cmpl $0x2, %eax
sete %al
cmpl $0x2, %ecx
sete %cl
orb %al, %cl
jne 0x4d46
movslq -0x68(%rbp), %rax
movl $0x0, %r14d
cmpl -0xb8(%rbp), %eax
jne 0x4d46
movq -0x60(%rbp), %r14
movq -0xb0(%rbp), %r12
xorl %ecx, %ecx
testl %eax, %eax
movl $0x0, %r13d
movq %rax, -0x30(%rbp)
cmovgl %eax, %r13d
movq %rcx, %r15
cmpq %rcx, %r13
je 0x4ecd
movq (%r14,%r15,8), %rsi
movq (%r12,%r15,8), %rdx
movq %rbx, %rdi
callq 0x6f09
leaq 0x1(%r15), %rcx
testl %eax, %eax
jne 0x4ead
xorl %r14d, %r14d
cmpq -0x30(%rbp), %r15
setge %r14b
jmp 0x4d46