// File: /workspace/github_c_makefile_star2_O2/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, %rbx
movl (%rsi), %r12d
movl (%rdx), %ecx
movb $0x1, %r13b
movl %r12d, %eax
orl %ecx, %eax
je 0x705f
movl %r12d, %eax
xorl $0x4, %eax
movl %ecx, %edi
xorl $0x4, %edi
orl %eax, %edi
je 0x705f
movl %r12d, %eax
xorl $0x7, %eax
movl %ecx, %edi
xorl $0x7, %edi
orl %eax, %edi
je 0x705f
movq 0x8(%rsi), %r15
movq 0x8(%rdx), %r14
cmpl $0x1, %r12d
jne 0x6fb0
cmpl $0x1, %ecx
jne 0x6fb0
movl (%r15), %r12d
cmpl $0x6, %r12d
je 0x6f84
movq %r15, %rsi
movq %r14, %rdx
cmpl $0x5, %r12d
jne 0x6f20
cmpl $0x5, (%r14)
jmp 0x6f88
cmpl $0x6, (%r14)
movq %r15, %rsi
movq %r14, %rdx
jne 0x6f20
movq 0x30(%r15), %rdi
movq 0x30(%r14), %rsi
callq 0x10e0
movq %r15, %rsi
movq %r14, %rdx
testl %eax, %eax
jne 0x6f20
jmp 0x705f
movl %r12d, %eax
xorl $0x2, %eax
movl %ecx, %edi
xorl $0x2, %edi
orl %eax, %edi
jne 0x6fe6
movl 0x10(%rdx), %r12d
movl 0x10(%rsi), %r13d
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x6f09
testl %eax, %eax
setne %al
cmpl %r12d, %r13d
sete %r13b
andb %al, %r13b
jmp 0x705f
movq 0x30(%rsi), %rdi
movq 0x30(%rdx), %rax
movl %r12d, %r9d
xorl $0x5, %r9d
movl %ecx, %r8d
xorl $0x5, %r8d
orl %r9d, %r8d
je 0x7014
movl %r12d, %r9d
xorl $0x6, %r9d
movl %ecx, %r8d
xorl $0x6, %r8d
orl %r9d, %r8d
jne 0x703d
movq %rax, %rsi
movq %rdi, %r14
callq 0x10e0
testl %eax, %eax
je 0x7028
xorl %r13d, %r13d
jmp 0x705f
movq 0x78(%rbx), %rdi
movq %r14, %rsi
callq 0x92a8
testq %rax, %rax
setne %r13b
jmp 0x705f
movl %r12d, %eax
xorl $0x8, %eax
movl %ecx, %edi
xorl $0x8, %edi
orl %eax, %edi
jne 0x7072
movq 0x40(%rsi), %rdi
movq 0x40(%rdx), %rsi
callq 0x10e0
testl %eax, %eax
sete %r13b
movzbl %r13b, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl $0x3, %r12d
xorl $0x3, %ecx
orl %r12d, %ecx
jne 0x7023
movslq 0x18(%rsi), %rax
movq %rax, -0x30(%rbp)
movq 0x20(%rsi), %rax
movq %rax, -0x48(%rbp)
movl 0x28(%rsi), %eax
movl %eax, -0x3c(%rbp)
movl 0x18(%rdx), %eax
movl %eax, -0x34(%rbp)
movq 0x20(%rdx), %r12
movl 0x28(%rdx), %eax
movl %eax, -0x38(%rbp)
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x6f09
testl %eax, %eax
je 0x7023
cmpl $0x1, -0x3c(%rbp)
jne 0x705f
cmpl $0x1, -0x38(%rbp)
jne 0x705f
xorl %r13d, %r13d
movl -0x34(%rbp), %eax
cmpl %eax, -0x30(%rbp)
jne 0x705f
movq -0x30(%rbp), %rax
testl %eax, %eax
movl $0x0, %r14d
cmovgl %eax, %r14d
movq %r13, %r15
cmpq %r13, %r14
je 0x7105
movq -0x48(%rbp), %rax
movq (%rax,%r15,8), %rsi
movq (%r12,%r15,8), %rdx
movq %rbx, %rdi
callq 0x6f09
leaq 0x1(%r15), %r13
testl %eax, %eax
jne 0x70e1
cmpq -0x30(%rbp), %r15
setge %r13b
jmp 0x705f
nop