// File: /workspace/github_c_makefile_star2_O3/ryvnf[P]czc/type.c
// Function: type_equals
bool type_equals(struct type *a, struct type *b)
{
    if (type_type(a->tag) != type_type(b->tag))
        return false;

    switch (type_type(a->tag)) {
        case PTR_TYPE_FLAG: {
            struct ptr_type *a2 = ptr_type(a);
            struct ptr_type *b2 = ptr_type(b);

            return type_equals(a2->to, b2->to);
        }
        case ARRAY_TYPE_FLAG: {
            struct array_type *a2 = array_type(a);
            struct array_type *b2 = array_type(b);

            if (a2->len != b2->len)
                return false;

            return type_equals(a2->of, b2->of);
        }
        case FUNC_TYPE_FLAG: {
            struct func_type *a2 = func_type(a);
            struct func_type *b2 = func_type(b);

            if (a2->n_params != b2->n_params)
                return false;

            for (size_t i = 0; i < a2->n_params; ++i) {
                if (!type_equals(a2->params[i], b2->params[i]))
                    return false;
            }

            return type_equals(a2->ret, b2->ret);
        }

        case VOID_TYPE_FLAG:
        case BOOL_TYPE_FLAG:
        case INT_TYPE_FLAG:
        case FLOAT_TYPE_FLAG:
            return (a->tag & ~LVAL_TYPE_FLAG) == (b->tag & ~LVAL_TYPE_FLAG);

        case STRUCT_TYPE_FLAG:
            return struct_type(a)->id == struct_type(b)->id;

        case EXTERN_TYPE_FLAG:
            return extern_type(a)->id == extern_type(b)->id;
    }

    unreachable();
    return false;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
movl (%rdi), %ecx
movl $0x3ff, %ebp            # imm = 0x3FF
movl %ecx, %edx
andl %ebp, %edx
movl (%rsi), %eax
movl %eax, %esi
andl %ebp, %esi
cmpl %esi, %edx
jne 0xbf32
movq %rdi, %r14
cmpl $0x1f, %edx
jg 0xbe9e
cmpl $0xf, %edx
jg 0xbef1
cmpl $0x8, %edx
jne 0xbf3f
testb $0x8, %cl
je 0xbf88
testb $0x8, %al
jne 0xbf15
jmp 0xbf88
cmpl $0x3f, %edx
jg 0xbf51
cmpl $0x20, %edx
jne 0xbff6
testb $0x20, %cl
je 0xbfab
testb $0x20, %al
je 0xbfab
movq 0x10(%r14), %rax
cmpq 0x10(%rbx), %rax
jne 0xbf32
testq %rax, %rax
je 0xbf15
xorl %r15d, %r15d
movq 0x20(%r14,%r15,8), %rdi
movq 0x20(%rbx,%r15,8), %rsi
callq 0xbe53
testb %al, %al
je 0xbf32
incq %r15
cmpq 0x10(%r14), %r15
jb 0xbed3
jmp 0xbf15
cmpl $0x10, %edx
jne 0xbff6
testb $0x10, %cl
je 0xbfce
testb $0x10, %al
je 0xbfce
movq 0x10(%r14), %rax
cmpq 0x10(%rbx), %rax
jne 0xbf32
movq 0x8(%rbx), %rbx
movq 0x8(%r14), %r14
movl (%r14), %ecx
movl %ecx, %edx
andl %ebp, %edx
movl (%rbx), %eax
movl %eax, %esi
andl %ebp, %esi
cmpl %esi, %edx
je 0xbe79
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leal -0x1(%rdx), %esi
cmpl $0x2, %esi
jb 0xbf73
cmpl $0x4, %edx
je 0xbf73
jmp 0xbff6
cmpl $0x40, %edx
je 0xbf7f
cmpl $0x80, %edx
je 0xbf73
cmpl $0x200, %edx            # imm = 0x200
jne 0xbff6
movl 0x4(%r14), %eax
cmpl 0x4(%rbx), %eax
jmp 0xbf7a
xorl %ecx, %eax
testl $0xfffffbff, %eax       # imm = 0xFFFFFBFF
sete %al
jmp 0xbf34
movl 0x1c(%r14), %eax
cmpl 0x1c(%rbx), %eax
jmp 0xbf7a
leaq 0x121d(%rip), %rdi      # 0xd1ac
leaq 0x29f4(%rip), %rsi      # 0xe98a
leaq 0x2a6f(%rip), %rcx      # 0xea0c
leaq 0x2a77(%rip), %r8       # 0xea1b
movl $0xe0, %edx
jmp 0xbfef
leaq 0x11fa(%rip), %rdi      # 0xd1ac
leaq 0x29d1(%rip), %rsi      # 0xe98a
leaq 0x2a80(%rip), %rcx      # 0xea40
leaq 0x2a89(%rip), %r8       # 0xea50
movl $0xec, %edx
jmp 0xbfef
leaq 0x11d7(%rip), %rdi      # 0xd1ac
leaq 0x29ae(%rip), %rsi      # 0xe98a
leaq 0x2a41(%rip), %rcx      # 0xea24
leaq 0x2a4b(%rip), %r8       # 0xea35
movl $0xe6, %edx
xorl %eax, %eax
callq 0x4eac
leaq 0x1ec3(%rip), %rdi      # 0xdec0
leaq 0x2986(%rip), %rsi      # 0xe98a
leaq 0x2a6f(%rip), %rcx      # 0xea7a
movl $0x1bb, %edx            # imm = 0x1BB
xorl %eax, %eax
callq 0x4eac