// File: /workspace/github_c_makefile_star2_O3/oridb[P]mc/parse/infer.c
// Function: tymatchrank
int
tymatchrank(Type *pat, Type *to)
{
	int match, q;
	size_t i;
	Ucon *puc, *tuc;

	pat = tysearch(pat);
	to = tysearch(to);
	if (pat->type == Typaram) {
		if (!pat->trneed)
			return 0;
		for (i = 0; bsiter(pat->trneed, &i); i++)
			if (!tryconstrain(to, traittab[i], 0))
				return -1;
		return 0;
	} else if (pat->type == Tyvar) {
		return 1;
	} else if (pat->type != to->type) {
		return -1;
	}

	match = 0;
	switch (pat->type) {
	case Tystruct:
		if (pat->nmemb != to->nmemb)
			return -1;
		for (i = 0; i < pat->nmemb; i++) {
			if (!streq(declname(pat->sdecls[i]),declname( to->sdecls[i])))
				return -1;
			q = tymatchrank(decltype(pat->sdecls[i]), decltype(to->sdecls[i]));
			if (q < 0)
				return -1;
			match += q;
		}
		break;
	case Tyunion:
		if (pat->nmemb != to->nmemb)
			return -1;
		for (i = 0; i < pat->nmemb; i++) {
			if (!nameeq(pat->udecls[i], to->udecls[i]))
				return -1;
			puc = pat->udecls[i];
			tuc = to->udecls[i];
			if (puc->etype && tuc->etype) {
				q = tymatchrank(puc->etype, tuc->etype);
				if (q < 0)
					return -1;
				match += q;
			} else if (puc->etype != tuc->etype) {
				return -1;
			}
		}
		break;
	case Tyname:
		if (!nameeq(pat->name, to->name))
			return -1;
		if (pat->narg != to->narg)
			return -1;
		for (i = 0; i < pat->narg; i++) {
			q = tymatchrank(pat->arg[i], to->arg[i]);
			if (q < 0)
				return -1;
			match += q;
		}
		break;
	case Tyarray:
		/* unsized arrays are ok */
		if (pat->asize && to->asize) {
			if (!!litvaleq(pat->asize->expr.args[0], to->asize->expr.args[0]))
				return -1;
		} else if (pat->asize != to->asize) {
			return -1;
		}
		else return tymatchrank(pat->sub[0], to->sub[0]);
		break;
	default:
		if (pat->nsub != to->nsub)
			break;
		if (pat->type == to->type)
			match = 1;
		for (i = 0; i < pat->nsub; i++) {
			q = tymatchrank(pat->sub[i], to->sub[i]);
			if (q < 0)
				return -1;
			match += q;
		}
		break;
	}
	return match;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x10, %rsp
testq %rdi, %rdi
je 0x170e3
leaq 0x4b101(%rip), %rax     # 0x621d0
movq (%rax), %rax
movq %rdi, %r12
movl 0x4(%rdi), %ecx
movq (%rax,%rcx,8), %rdi
testq %rdi, %rdi
jne 0x170d2
jmp 0x170e6
xorl %r12d, %r12d
testq %rsi, %rsi
je 0x17106
leaq 0x4b0de(%rip), %rax     # 0x621d0
movq (%rax), %rax
movq %rsi, %rbx
movl 0x4(%rsi), %ecx
movq (%rax,%rcx,8), %rsi
testq %rsi, %rsi
jne 0x170f5
jmp 0x17108
xorl %ebx, %ebx
movl (%r12), %eax
movl $0x1, %r14d
cmpl $0x19, %eax
je 0x173df
cmpl $0x1a, %eax
jne 0x17195
movq 0x80(%r12), %rdi
xorl %r14d, %r14d
testq %rdi, %rdi
je 0x173df
leaq 0x8(%rsp), %rsi
movq $0x0, (%rsi)
callq 0x2d2a6
testl %eax, %eax
je 0x173df
leaq 0x4b0a4(%rip), %r15     # 0x621f8
leaq 0x8(%rsp), %r14
movq (%r15), %rax
movq 0x8(%rsp), %rcx
movq (%rax,%rcx,8), %rsi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x17416
testl %eax, %eax
je 0x173d4
incq 0x8(%rsp)
movq 0x80(%r12), %rdi
movq %r14, %rsi
callq 0x2d2a6
testl %eax, %eax
jne 0x17159
jmp 0x173dc
cmpl (%rbx), %eax
jne 0x173d4
addl $-0x15, %eax
cmpl $0x7, %eax
ja 0x17392
leaq 0x1e7f0(%rip), %rcx     # 0x359a0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x88(%r12), %rax
movq 0x88(%rbx), %rcx
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
testq %rax, %rax
je 0x173f0
testq %rcx, %rcx
je 0x173df
movq 0x50(%rax), %rax
movq (%rax), %rdi
movq 0x50(%rcx), %rax
movq (%rax), %rsi
callq 0x1e3e3
xorl %r14d, %r14d
negl %eax
sbbl %r14d, %r14d
jmp 0x173df
movq 0x78(%r12), %rax
cmpq 0x78(%rbx), %rax
jne 0x173d4
testq %rax, %rax
je 0x173dc
xorl %r14d, %r14d
xorl %r15d, %r15d
movq 0x88(%r12), %rax
movq (%rax,%r15,8), %rdi
movq 0x88(%rbx), %rax
movq (%rax,%r15,8), %rsi
callq 0x1e523
testl %eax, %eax
je 0x173d4
movq 0x88(%r12), %rax
movq (%rax,%r15,8), %rax
movq 0x88(%rbx), %rcx
movq (%rcx,%r15,8), %rcx
movq 0x28(%rax), %rdi
movq 0x28(%rcx), %rsi
testq %rdi, %rdi
je 0x17281
testq %rsi, %rsi
je 0x173d4
callq 0x170b6
testl %eax, %eax
js 0x173d4
addl %eax, %r14d
jmp 0x1728a
cmpq %rsi, %rdi
jne 0x173d4
incq %r15
cmpq 0x78(%r12), %r15
jb 0x1721e
jmp 0x173df
movq 0x78(%r12), %rax
cmpq 0x78(%rbx), %rax
jne 0x173d4
testq %rax, %rax
je 0x173dc
xorl %r14d, %r14d
xorl %r13d, %r13d
movq 0x88(%r12), %rax
movq (%rax,%r13,8), %rdi
callq 0x1e2ed
movq %rax, %r15
movq 0x88(%rbx), %rax
movq (%rax,%r13,8), %rdi
callq 0x1e2ed
movq %r15, %rdi
movq %rax, %rsi
callq 0x2db3b
testl %eax, %eax
je 0x173d4
movq 0x88(%r12), %rax
movq (%rax,%r13,8), %rdi
callq 0x1e31c
movq %rax, %r15
movq 0x88(%rbx), %rax
movq (%rax,%r13,8), %rdi
callq 0x1e31c
movq %r15, %rdi
movq %rax, %rsi
callq 0x170b6
testl %eax, %eax
js 0x173d4
addl %eax, %r14d
incq %r13
cmpq 0x78(%r12), %r13
jb 0x172b7
jmp 0x173df
movq 0x88(%r12), %rdi
movq 0x88(%rbx), %rsi
callq 0x1e523
testl %eax, %eax
je 0x173d4
movq 0x48(%r12), %rax
cmpq 0x48(%rbx), %rax
jne 0x173d4
testq %rax, %rax
je 0x173dc
xorl %r14d, %r14d
xorl %r15d, %r15d
movq 0x40(%r12), %rax
movq (%rax,%r15,8), %rdi
movq 0x40(%rbx), %rax
movq (%rax,%r15,8), %rsi
callq 0x170b6
testl %eax, %eax
js 0x173d4
addl %eax, %r14d
incq %r15
cmpq 0x48(%r12), %r15
jb 0x17369
jmp 0x173df
movq 0x70(%r12), %rax
cmpq 0x70(%rbx), %rax
jne 0x173dc
testq %rax, %rax
je 0x173df
movl $0x1, %r14d
xorl %r15d, %r15d
movq 0x68(%r12), %rax
movq (%rax,%r15,8), %rdi
movq 0x68(%rbx), %rax
movq (%rax,%r15,8), %rsi
callq 0x170b6
testl %eax, %eax
js 0x173d4
addl %eax, %r14d
incq %r15
cmpq 0x70(%r12), %r15
jb 0x173ab
jmp 0x173df
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
jmp 0x173df
xorl %r14d, %r14d
movl %r14d, %eax
addq $0x10, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
cmpq %rcx, %rax
jne 0x173df
movq 0x68(%r12), %rax
movq (%rax), %rdi
movq 0x68(%rbx), %rax
movq (%rax), %rsi
addq $0x10, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
jmp 0x170b6