// File: /workspace/github_c_makefile_star2_O1/hsjoihs[P]c-compiler/typecheck_expression.c
// Function: is_strictly_equal
static int is_strictly_equal(const struct AnalyzerState *ptr_ps,
                             const struct Type *ref_t1,
                             const struct Type *ref_t2)
{
	const struct Type t1 = *ref_t1;
	const struct Type t2 = *ref_t2;
	if (t1.type_category == INT_ && t2.type_category == INT_) {
		return 1;
	}

	if (t1.type_category == CHAR_ && t2.type_category == CHAR_) {
		return 1;
	}

	if (t1.type_category == VOID_ && t2.type_category == VOID_) {
		return 1;
	}

	if (t1.type_category == PTR_ && t2.type_category == PTR_) {

		/* pointer to incomplete types */
		if (t1.derived_from->type_category == STRUCT_NOT_UNION &&
		    t2.derived_from->type_category == STRUCT_NOT_UNION &&
		    strcmp(t1.derived_from->s.struct_or_union_tag,
		           t2.derived_from->s.struct_or_union_tag) == 0) {
			return 1;
		}

		/* pointer to incomplete types */
		if (t1.derived_from->type_category == UNION &&
		    t2.derived_from->type_category == UNION &&
		    strcmp(t1.derived_from->s.struct_or_union_tag,
		           t2.derived_from->s.struct_or_union_tag) == 0) {
			return 1;
		}

		return is_strictly_equal(ptr_ps, t1.derived_from, t2.derived_from);
	}

	if (t1.type_category == ARRAY && t2.type_category == ARRAY) {
		return is_strictly_equal(ptr_ps, t1.derived_from, t2.derived_from) &&
		       (t1.array_length == t2.array_length);
	}

	if (t1.type_category == STRUCT_NOT_UNION &&
	    t2.type_category == STRUCT_NOT_UNION) {
		if ((0)) { /* both are local */
			unsupported("struct type declared locally");
		}
		return strcmp(t1.s.struct_or_union_tag, t2.s.struct_or_union_tag) ==
		           0 &&
		       lookup(ptr_ps->global_struct_or_union_tag_map,
		              t1.s.struct_or_union_tag);
	}

	if (t1.type_category == UNION && t2.type_category == UNION) {
		if ((0)) { /* both are local */
			unsupported("union type declared locally");
		}
		return strcmp(t1.s.struct_or_union_tag, t2.s.struct_or_union_tag) ==
		           0 &&
		       lookup(ptr_ps->global_struct_or_union_tag_map,
		              t1.s.struct_or_union_tag);
	}

	if (t1.type_category == ENUM_ && t2.type_category == ENUM_) {
		if ((0)) { /* both are local */
			unsupported("enum type declared locally");
		}
		return strcmp(t1.e.enum_tag, t2.e.enum_tag) == 0;
	}

	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 == VALID &&
		    t2.param_infos_validity == VALID) {
			if (t1.param_infos.length != t2.param_infos.length) {
				return 0;
			}

			for (int i = 0; i < t1.param_infos.length; i++) {
				if (!is_strictly_equal(ptr_ps, t1.param_infos.vector[i],
				                       t2.param_infos.vector[i])) {
					return 0;
				}
			}
			return 1;
		} else if (t1.param_infos_validity == INVALID ||
		           t2.param_infos_validity ==
		               INVALID) { /* when invalid, it matches no matter what */
			return 1;
		} else { /* one is VA_ARGS, the other is valid */
#ifdef __STDC__
#warning should typecheck
#endif
			return 1;
		}
	}

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, -0x30(%rbp)
movl (%rsi), %ecx
movl (%rdx), %r8d
movl $0x1, %r9d
movl %ecx, %eax
orl %r8d, %eax
je 0x7f6a
movl %ecx, %eax
xorl $0x4, %eax
movl %r8d, %edi
xorl $0x4, %edi
orl %eax, %edi
je 0x7f6a
movl %ecx, %eax
xorl $0x7, %eax
movl %r8d, %edi
xorl $0x7, %edi
orl %eax, %edi
je 0x7f6a
movq 0x8(%rsi), %r15
movl 0x10(%rsi), %ebx
movl 0x18(%rsi), %r10d
movq 0x20(%rsi), %r11
movl 0x28(%rsi), %eax
movl %eax, -0x3c(%rbp)
movq 0x30(%rsi), %r13
movq 0x40(%rsi), %rdi
movq 0x8(%rdx), %r12
movl 0x10(%rdx), %r14d
movl 0x18(%rdx), %eax
movl %eax, -0x34(%rbp)
movq 0x20(%rdx), %r9
movl 0x28(%rdx), %eax
movl %eax, -0x38(%rbp)
movq 0x30(%rdx), %rax
movq 0x40(%rdx), %rsi
cmpl $0x1, %ecx
jne 0x7ec4
cmpl $0x1, %r8d
jne 0x7ec4
movl (%r15), %ebx
cmpl $0x6, %ebx
je 0x7e8c
movq %r15, %rsi
movq %r12, %rdx
cmpl $0x5, %ebx
jne 0x7db7
cmpl $0x5, (%r12)
jne 0x7e7d
movq 0x30(%r15), %rdi
movq 0x30(%r12), %rsi
callq 0x10e0
movl $0x1, %r9d
testl %eax, %eax
je 0x7f6a
movq %r15, %rsi
movq %r12, %rdx
cmpl $0x6, %ebx
jne 0x7db7
cmpl $0x6, (%r12)
movq %r15, %rsi
movq %r12, %rdx
jne 0x7db7
movq 0x30(%r15), %rdi
movq 0x30(%r12), %rsi
callq 0x10e0
movl $0x1, %r9d
movq %r15, %rsi
movq %r12, %rdx
testl %eax, %eax
jne 0x7db7
jmp 0x7f6a
movq %r9, -0x48(%rbp)
movl %ecx, %edx
xorl $0x2, %edx
movl %r8d, %r9d
xorl $0x2, %r9d
orl %edx, %r9d
jne 0x7efb
movq -0x30(%rbp), %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x7da2
testl %eax, %eax
setne %al
cmpl %r14d, %ebx
sete %cl
andb %al, %cl
movzbl %cl, %r9d
jmp 0x7f6a
movl %ecx, %edx
xorl $0x5, %edx
movl %r8d, %r9d
xorl $0x5, %r9d
orl %edx, %r9d
je 0x7f1d
movl %ecx, %edx
xorl $0x6, %edx
movl %r8d, %r9d
xorl $0x6, %r9d
orl %edx, %r9d
jne 0x7f4d
movq %r13, %rdi
movq %rax, %rsi
callq 0x10e0
testl %eax, %eax
je 0x7f31
xorl %r9d, %r9d
jmp 0x7f6a
movq -0x30(%rbp), %rax
movq 0x78(%rax), %rdi
movq %r13, %rsi
callq 0xa32d
xorl %r9d, %r9d
testq %rax, %rax
setne %r9b
jmp 0x7f6a
movl %ecx, %eax
xorl $0x8, %eax
movl %r8d, %edx
xorl $0x8, %edx
orl %eax, %edx
jne 0x7f7c
callq 0x10e0
xorl %r9d, %r9d
testl %eax, %eax
sete %r9b
movl %r9d, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl $0x3, %ecx
xorl $0x3, %r8d
orl %ecx, %r8d
jne 0x7f2c
movq %r11, %r13
movq %r10, %r14
movq -0x30(%rbp), %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x7da2
testl %eax, %eax
je 0x7f2c
cmpl $0x1, -0x3c(%rbp)
jne 0x8020
cmpl $0x1, -0x38(%rbp)
movl $0x1, %r9d
jne 0x7f6a
movq %r14, %rax
movl $0x0, %r9d
cmpl -0x34(%rbp), %eax
jne 0x7f6a
testl %eax, %eax
setle %bl
jle 0x8017
movq (%r13), %rsi
movq -0x48(%rbp), %rax
movq (%rax), %rdx
movq -0x30(%rbp), %rdi
callq 0x7da2
testl %eax, %eax
je 0x8017
movl $0x1, %ecx
movq %r14, %rdx
movq %rcx, %rbx
cmpq %rcx, %rdx
je 0x8011
movq (%r13,%rbx,8), %rsi
movq -0x48(%rbp), %rax
movq (%rax,%rbx,8), %rdx
movq -0x30(%rbp), %rdi
callq 0x7da2
movq %r14, %rdx
leaq 0x1(%rbx), %rcx
testl %eax, %eax
jne 0x7fe8
cmpq %rdx, %rbx
setae %bl
movzbl %bl, %r9d
jmp 0x7f6a
movl $0x1, %r9d
jmp 0x7f6a