// File: /workspace/github_c_makefile_star2_O1/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
movq %rdi, %r14
movl $0x3ff, %ebp            # imm = 0x3FF
movl (%r14), %ecx
movl %ecx, %edx
andl %ebp, %edx
movl (%rbx), %eax
movl %eax, %esi
andl %ebp, %esi
cmpl %esi, %edx
jne 0xc195
cmpl $0x1f, %edx
jg 0xc10f
cmpl $0xf, %edx
jg 0xc164
cmpl $0x8, %edx
jne 0xc199
testb $0x8, %cl
je 0xc1eb
testb $0x8, %al
jne 0xc188
jmp 0xc1eb
cmpl $0x3f, %edx
jg 0xc1ab
cmpl $0x20, %edx
jne 0xc259
testb $0x20, %cl
je 0xc20e
testb $0x20, %al
je 0xc20e
movq 0x10(%r14), %rax
cmpq 0x10(%rbx), %rax
jne 0xc195
cmpq $0x0, 0x10(%r14)
je 0xc188
xorl %r15d, %r15d
movq 0x20(%r14,%r15,8), %rdi
movq 0x20(%rbx,%r15,8), %rsi
callq 0xc0c3
testb %al, %al
je 0xc195
incq %r15
cmpq 0x10(%r14), %r15
jb 0xc146
jmp 0xc188
cmpl $0x10, %edx
jne 0xc259
testb $0x10, %cl
je 0xc231
testb $0x10, %al
je 0xc231
movq 0x10(%r14), %rax
cmpq 0x10(%rbx), %rax
jne 0xc195
movq 0x8(%r14), %r14
movq 0x8(%rbx), %rbx
jmp 0xc0d5
xorl %eax, %eax
jmp 0xc1d7
leal -0x1(%rdx), %esi
cmpl $0x2, %esi
jb 0xc1cd
cmpl $0x4, %edx
je 0xc1cd
jmp 0xc259
cmpl $0x40, %edx
je 0xc1e2
cmpl $0x80, %edx
je 0xc1cd
cmpl $0x200, %edx            # imm = 0x200
jne 0xc259
movl 0x4(%r14), %eax
cmpl 0x4(%rbx), %eax
jmp 0xc1d4
xorl %ecx, %eax
testl $0xfffffbff, %eax       # imm = 0xFFFFFBFF
sete %al
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
movl 0x1c(%r14), %eax
cmpl 0x1c(%rbx), %eax
jmp 0xc1d4
leaq 0xfba(%rip), %rdi       # 0xd1ac
leaq 0x27a1(%rip), %rsi      # 0xe99a
leaq 0x281c(%rip), %rcx      # 0xea1c
leaq 0x2824(%rip), %r8       # 0xea2b
movl $0xe0, %edx
jmp 0xc252
leaq 0xf97(%rip), %rdi       # 0xd1ac
leaq 0x277e(%rip), %rsi      # 0xe99a
leaq 0x282d(%rip), %rcx      # 0xea50
leaq 0x2836(%rip), %r8       # 0xea60
movl $0xec, %edx
jmp 0xc252
leaq 0xf74(%rip), %rdi       # 0xd1ac
leaq 0x275b(%rip), %rsi      # 0xe99a
leaq 0x27ee(%rip), %rcx      # 0xea34
leaq 0x27f8(%rip), %r8       # 0xea45
movl $0xe6, %edx
xorl %eax, %eax
callq 0x4f1c
leaq 0x1c60(%rip), %rdi      # 0xdec0
leaq 0x2733(%rip), %rsi      # 0xe99a
leaq 0x281c(%rip), %rcx      # 0xea8a
movl $0x1bb, %edx            # imm = 0x1BB
xorl %eax, %eax
callq 0x4f1c