// File: /workspace/github_c_makefile_star2_O3/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
movl (%rsi), %r13d
movl (%rdx), %ecx
movb $0x1, %r12b
movl %r13d, %eax
orl %ecx, %eax
jne 0x7f89
movb $0x1, %r12b
movzbl %r12b, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %rbx
movq %r15, %rdx
movq %r14, %r8
movq 0x8(%r15), %r15
movq 0x8(%r14), %r14
cmpl $0x4, %r13d
jne 0x7fab
cmpl $0x4, %ecx
je 0x7f73
cmpl $0x7, %r13d
jne 0x7fb6
cmpl $0x7, %ecx
je 0x7f73
cmpl $0x1, %r13d
jne 0x8017
cmpl $0x1, %ecx
jne 0x8017
movl (%r15), %r13d
movl (%r14), %ecx
cmpl $0x6, %r13d
je 0x7fec
cmpl $0x5, %r13d
jne 0x800b
cmpl $0x5, %ecx
jne 0x800b
movq 0x30(%r15), %rdi
movq 0x30(%r14), %rsi
callq 0x10e0
movl $0x5, %ecx
jmp 0x8003
cmpl $0x6, %ecx
jne 0x800b
movq 0x30(%r15), %rdi
movq 0x30(%r14), %rsi
callq 0x10e0
movl $0x6, %ecx
testl %eax, %eax
je 0x7f76
movl %r13d, %eax
orl %ecx, %eax
jne 0x7f92
jmp 0x7f76
movl 0x18(%rdx), %r9d
movq 0x20(%rdx), %r10
movl 0x28(%rdx), %eax
movl %eax, -0x34(%rbp)
movq 0x30(%rdx), %r12
movq 0x40(%rdx), %rdi
movl 0x18(%r8), %eax
movl %eax, -0x2c(%rbp)
movq 0x20(%r8), %r11
movl 0x28(%r8), %eax
movl %eax, -0x30(%rbp)
movq 0x30(%r8), %rax
movq 0x40(%r8), %rsi
cmpl $0x2, %r13d
jne 0x807c
cmpl $0x2, %ecx
jne 0x807c
movl 0x10(%r8), %r12d
movl 0x10(%rdx), %r13d
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x7f53
testl %eax, %eax
setne %al
cmpl %r12d, %r13d
sete %r12b
andb %al, %r12b
jmp 0x7f76
cmpl $0x5, %r13d
jne 0x8087
cmpl $0x5, %ecx
je 0x8092
cmpl $0x6, %r13d
jne 0x80c1
cmpl $0x6, %ecx
jne 0x80c1
movq %r12, %rdi
movq %rax, %rsi
callq 0x10e0
testl %eax, %eax
je 0x80a9
xorl %r12d, %r12d
jmp 0x7f76
movq 0x78(%rbx), %rdi
movq %r12, %rsi
callq 0xa39c
testq %rax, %rax
setne %r12b
jmp 0x7f76
cmpl $0x8, %r13d
jne 0x80dc
cmpl $0x8, %ecx
jne 0x80dc
callq 0x10e0
testl %eax, %eax
sete %r12b
jmp 0x7f76
xorl %r12d, %r12d
cmpl $0x3, %r13d
jne 0x7f76
cmpl $0x3, %ecx
jne 0x7f76
movq %r11, -0x40(%rbp)
movq %r10, -0x48(%rbp)
movq %r9, %r13
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x7f53
testl %eax, %eax
je 0x80a1
cmpl $0x1, -0x34(%rbp)
jne 0x7f73
cmpl $0x1, -0x30(%rbp)
jne 0x7f73
movq %r13, %rax
cmpl -0x2c(%rbp), %eax
jne 0x80a1
movb $0x1, %r12b
testl %eax, %eax
movq -0x48(%rbp), %rax
movq -0x40(%rbp), %rcx
jle 0x7f76
movq (%rax), %rsi
movq (%rcx), %rdx
movq %rbx, %rdi
callq 0x7f53
testl %eax, %eax
je 0x80a1
movl $0x1, %ecx
movq %r13, %rdx
movq %rcx, %r14
cmpq %rcx, %rdx
je 0x818b
movq -0x48(%rbp), %rax
movq (%rax,%r14,8), %rsi
movq -0x40(%rbp), %rax
movq (%rax,%r14,8), %rdx
movq %rbx, %rdi
callq 0x7f53
movq %r13, %rdx
leaq 0x1(%r14), %rcx
testl %eax, %eax
jne 0x8160
cmpq %rdx, %r14
setae %r12b
jmp 0x7f76
nop