// File: /workspace/github_c_makefile_star2_O1/lucvoo[P]sparse-dev/evaluate.c
// Function: type_difference
const char *type_difference(struct ctype *c1, struct ctype *c2,
	unsigned long mod1, unsigned long mod2)
{
	struct ident *as1 = c1->as, *as2 = c2->as;
	struct symbol *t1 = c1->base_type;
	struct symbol *t2 = c2->base_type;
	int move1 = 1, move2 = 1;
	mod1 |= c1->modifiers;
	mod2 |= c2->modifiers;
	for (;;) {
		unsigned long diff;
		int type;
		struct symbol *base1 = t1->ctype.base_type;
		struct symbol *base2 = t2->ctype.base_type;

		/*
		 * FIXME! Collect alignment and context too here!
		 */
		if (move1) {
			if (t1 && t1->type != SYM_PTR) {
				mod1 |= t1->ctype.modifiers;
				combine_address_space(t1->pos, &as1, t1->ctype.as);
			}
			move1 = 0;
		}

		if (move2) {
			if (t2 && t2->type != SYM_PTR) {
				mod2 |= t2->ctype.modifiers;
				combine_address_space(t2->pos, &as2, t2->ctype.as);
			}
			move2 = 0;
		}

		if (t1 == t2)
			break;
		if (!t1 || !t2)
			return "different types";

		if (t1->type == SYM_NODE || t1->type == SYM_ENUM) {
			t1 = base1;
			move1 = 1;
			if (!t1)
				return "bad types";
			continue;
		}

		if (t2->type == SYM_NODE || t2->type == SYM_ENUM) {
			t2 = base2;
			move2 = 1;
			if (!t2)
				return "bad types";
			continue;
		}

		move1 = move2 = 1;
		type = t1->type;
		if (type != t2->type)
			return "different base types";

		switch (type) {
		default:
			sparse_error(t1->pos,
				     "internal error: bad type in derived(%d)",
				     type);
			return "bad types";
		case SYM_RESTRICT:
			return "different base types";
		case SYM_UNION:
		case SYM_STRUCT:
			/* allow definition of incomplete structs and unions */
			if (t1->ident == t2->ident)
			  return NULL;
			return "different base types";
		case SYM_ARRAY:
			/* XXX: we ought to compare sizes */
			break;
		case SYM_PTR:
			if (as1 != as2)
				return "different address spaces";
			/* MOD_SPECIFIER is due to idiocy in parse.c */
			if ((mod1 ^ mod2) & ~MOD_IGNORE & ~MOD_SPECIFIER)
				return "different modifiers";
			/* we could be lazier here */
			base1 = examine_pointer_target(t1);
			base2 = examine_pointer_target(t2);
			mod1 = t1->ctype.modifiers;
			as1 = t1->ctype.as;
			mod2 = t2->ctype.modifiers;
			as2 = t2->ctype.as;
			break;
		case SYM_FN: {
			struct symbol *arg1, *arg2;
			int i;

			if (as1 != as2)
				return "different address spaces";
			if ((mod1 ^ mod2) & ~MOD_IGNORE & ~MOD_SIGNEDNESS)
				return "different modifiers";
			mod1 = t1->ctype.modifiers;
			as1 = t1->ctype.as;
			mod2 = t2->ctype.modifiers;
			as2 = t2->ctype.as;

			if (t1->variadic != t2->variadic)
				return "incompatible variadic arguments";
			examine_fn_arguments(t1);
			examine_fn_arguments(t2);
			PREPARE_PTR_LIST(t1->arguments, arg1);
			PREPARE_PTR_LIST(t2->arguments, arg2);
			i = 1;
			for (;;) {
				const char *diffstr;
				if (!arg1 && !arg2)
					break;
				if (!arg1 || !arg2)
					return "different argument counts";
				diffstr = type_difference(&arg1->ctype,
							  &arg2->ctype,
							  MOD_IGN, MOD_IGN);
				if (diffstr) {
					static char argdiff[80];
					sprintf(argdiff, "incompatible argument %d (%s)", i, diffstr);
					return argdiff;
				}
				NEXT_PTR_LIST(arg1);
				NEXT_PTR_LIST(arg2);
				i++;
			}
			FINISH_PTR_LIST(arg2);
			FINISH_PTR_LIST(arg1);
			break;
		}
		case SYM_BASETYPE:
			if (as1 != as2)
				return "different address spaces";
			if (base1 != base2)
				return "different base types";
			if (t1->rank != t2->rank)
				return "different type sizes";
			diff = (mod1 ^ mod2) & ~MOD_IGNORE;
			if (!diff)
				return NULL;
			else if (diff & ~MOD_SIGNEDNESS)
				return "different modifiers";
			else
				return "different signedness";
		}
		t1 = base1;
		t2 = base2;
	}
	if (as1 != as2)
		return "different address spaces";
	if ((mod1 ^ mod2) & ~MOD_IGNORE & ~MOD_SIGNEDNESS)
		return "different modifiers";
	return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %rdx, %r8
movq (%rdi), %r12
movq 0x20(%rdi), %r10
movq (%rsi), %r13
orq 0x8(%rdi), %r8
orq 0x8(%rsi), %rcx
movq 0x20(%rsi), %r11
movl $0x1, %ebx
leaq 0x18c31(%rip), %rsi     # 0x4ac84
leaq 0x18c3a(%rip), %rdi     # 0x4ac94
movl $0x1, %r14d
movq 0x60(%r12), %r9
movq 0x60(%r13), %rbp
testl %ebx, %ebx
je 0x320e8
testq %r12, %r12
je 0x320e8
cmpb $0x4, (%r12)
je 0x320e8
orq 0x68(%r12), %r8
movq 0x80(%r12), %rax
testq %rax, %rax
je 0x320e8
testq %r10, %r10
je 0x320e5
cmpq %rax, %r10
je 0x320e8
movq 0x4(%r12), %rdi
leaq 0x15a1b(%rip), %rsi     # 0x47abc
xorl %eax, %eax
movq %r8, 0x20(%rsp)
movq %rcx, %r15
movq %rbp, 0x10(%rsp)
movq %r11, %rbp
movq %r9, %rbx
callq 0x11a38
movq %rbx, %r9
movq %rbp, %r11
movq 0x10(%rsp), %rbp
leaq 0x18bc7(%rip), %rdi     # 0x4ac94
leaq 0x18bb0(%rip), %rsi     # 0x4ac84
movq %r15, %rcx
movq 0x20(%rsp), %r8
leaq 0x342fd(%rip), %r10     # 0x663e0
jmp 0x320e8
movq %rax, %r10
testl %r14d, %r14d
je 0x32161
testq %r13, %r13
je 0x32161
cmpb $0x4, (%r13)
je 0x32161
orq 0x68(%r13), %rcx
movq 0x80(%r13), %rax
testq %rax, %rax
je 0x32161
testq %r11, %r11
je 0x3215e
cmpq %rax, %r11
je 0x32161
movq 0x4(%r13), %rdi
leaq 0x1599e(%rip), %rsi     # 0x47abc
xorl %eax, %eax
movq %r8, %rbx
movq %rcx, %r14
movq %r10, %r15
movq %rbp, 0x10(%rsp)
movq %r9, %rbp
callq 0x11a38
movq %rbp, %r9
movq 0x10(%rsp), %rbp
movq %r15, %r10
leaq 0x18b4c(%rip), %rdi     # 0x4ac94
leaq 0x18b35(%rip), %rsi     # 0x4ac84
movq %r14, %rcx
movq %rbx, %r8
leaq 0x34284(%rip), %r11     # 0x663e0
jmp 0x32161
movq %rax, %r11
xorl %r14d, %r14d
cmpq %r13, %r12
je 0x321ae
movl $0x1, %r15d
testq %r13, %r13
je 0x321b8
testq %r12, %r12
je 0x321b8
movl (%r12), %eax
cmpb $0x9, %al
je 0x32189
movzbl %al, %edx
cmpl $0x3, %edx
jne 0x321d7
xorl %eax, %eax
testq %r9, %r9
setne %al
leal 0x1(%rax,%rax), %r15d
movq 0x8(%rsp), %rax
cmoveq %rdi, %rax
movq %rax, 0x8(%rsp)
movl $0x1, %ebx
movq %r9, %r12
jmp 0x321bf
movl $0x2, %r15d
xorl %ebx, %ebx
jmp 0x321bf
xorl %ebx, %ebx
movq %rsi, 0x8(%rsp)
testl %r15d, %r15d
je 0x32060
cmpl $0x3, %r15d
je 0x32060
jmp 0x32752
movl (%r13), %eax
cmpb $0x9, %al
je 0x321e7
movzbl %al, %eax
cmpl $0x3, %eax
jne 0x32212
xorl %eax, %eax
testq %rbp, %rbp
setne %al
movq 0x8(%rsp), %rdx
cmoveq %rdi, %rdx
movq %rdx, 0x8(%rsp)
leal 0x1(,%rax,2), %r15d
movl $0x1, %r14d
xorl %ebx, %ebx
movq %rbp, %r13
jmp 0x321bf
movl $0x1, %ebx
cmpl %eax, %edx
jne 0x322c8
movq %r9, 0x10(%rsp)
leal -0x2(%rdx), %eax
cmpl $0xb, %eax
ja 0x32265
leaq 0x1882d(%rip), %r9      # 0x4aa60
movslq (%r9,%rax,4), %rax
addq %r9, %rax
jmpq *%rax
movq 0x18(%r12), %rax
cmpq 0x18(%r13), %rax
leaq 0x18a52(%rip), %rdx     # 0x4ac9e
movl $0x0, %eax
cmoveq %rax, %rdx
movq %rdx, 0x8(%rsp)
movl $0x1, %r14d
jmp 0x321bf
movq 0x4(%r12), %rdi
leaq 0x18a42(%rip), %rsi     # 0x4acb3
xorl %eax, %eax
movq %r8, 0x20(%rsp)
movq %rcx, %r15
movq %r10, %rbp
movq %r11, %r14
callq 0x11a38
movq %r14, %r11
movq %rbp, %r10
leaq 0x18a01(%rip), %rdi     # 0x4ac94
leaq 0x189ea(%rip), %rsi     # 0x4ac84
movq %r15, %rcx
movq 0x20(%rsp), %r8
movl $0x1, %r14d
movl $0x1, %r15d
movq %rdi, 0x8(%rsp)
jmp 0x321bf
cmpq %r11, %r10
jne 0x322e4
cmpq %rbp, 0x10(%rsp)
je 0x32402
movl $0x1, %r14d
leaq 0x189c9(%rip), %rax     # 0x4ac9e
movq %rax, 0x8(%rsp)
jmp 0x321bf
cmpq %r11, %r10
je 0x32313
movl $0x1, %r14d
leaq 0x189ea(%rip), %rax     # 0x4acdb
jmp 0x322d5
cmpq %r11, %r10
je 0x32334
leaq 0x189dc(%rip), %rax     # 0x4acdb
movq 0x10(%rsp), %rdx
jmp 0x32710
movq 0x10(%rsp), %rdx
jmp 0x32725
movq %rcx, %rax
xorq %r8, %rax
testq $-0x2043e1e0, %rax      # imm = 0xDFBC1E20
je 0x32424
movl $0x1, %r14d
leaq 0x189c2(%rip), %rax     # 0x4acf4
jmp 0x322d5
movq %rcx, %rdx
xorq %r8, %rdx
leaq 0x189b3(%rip), %rax     # 0x4acf4
testq $-0x2043e1e0, %rdx      # imm = 0xDFBC1E20
movq 0x10(%rsp), %rdx
jne 0x32710
movq 0x68(%r12), %r8
movq 0x80(%r12), %r10
movq 0x68(%r13), %rcx
movq 0x80(%r13), %r11
movl 0x54(%r13), %eax
xorl 0x54(%r12), %eax
btl $0x9, %eax
jb 0x32468
movq %r11, 0x40(%rsp)
movq %r10, 0x48(%rsp)
movq %rcx, 0x50(%rsp)
movq %r8, 0x20(%rsp)
movq %r12, %rdi
callq 0x32794
movq %r13, %rdi
callq 0x32794
movq 0x88(%r12), %rax
testq %rax, %rax
je 0x3249f
movq %rax, %r9
movq 0x20(%rsp), %r8
movq 0x50(%rsp), %rcx
leaq 0x188bd(%rip), %rsi     # 0x4ac84
leaq 0x188c6(%rip), %rdi     # 0x4ac94
movq 0x48(%rsp), %r10
movq 0x40(%rsp), %r11
cmpb $0x0, (%r9)
jg 0x324d8
movq 0x10(%r9), %r9
cmpq %rax, %r9
jne 0x323d8
movq $0x0, 0x18(%rsp)
movq $0x0, 0x30(%rsp)
jmp 0x324ef
movl 0x54(%r13), %eax
xorl 0x54(%r12), %eax
testl $0x3800000, %eax        # imm = 0x3800000
je 0x32474
movl $0x1, %r14d
leaq 0x18941(%rip), %rax     # 0x4ad60
jmp 0x322d5
movq %r12, %rdi
callq 0x2bfd0
movq %rax, %rbx
movq %r13, %rdi
callq 0x2bfd0
movq %rbx, %rdx
leaq 0x18853(%rip), %rdi     # 0x4ac94
leaq 0x1883c(%rip), %rsi     # 0x4ac84
movq %rax, %rbp
movq 0x68(%r12), %r8
movq 0x80(%r12), %r10
movq 0x68(%r13), %rcx
movq 0x80(%r13), %r11
jmp 0x32725
leaq 0x18899(%rip), %rax     # 0x4ad08
jmp 0x32710
movq %rcx, %rax
xorq %r8, %rax
testq $-0x204381e0, %rax      # imm = 0xDFBC7E20
je 0x3273e
testq $-0x2043e1e0, %rax      # imm = 0xDFBC1E20
leaq 0x18861(%rip), %rdx     # 0x4acf4
leaq 0x188db(%rip), %rax     # 0x4ad75
jmp 0x32251
movq $0x0, 0x18(%rsp)
xorl %r9d, %r9d
movq $0x0, 0x30(%rsp)
movq 0x20(%rsp), %r8
movq 0x50(%rsp), %rcx
leaq 0x187bf(%rip), %rsi     # 0x4ac84
leaq 0x187c8(%rip), %rdi     # 0x4ac94
movq 0x48(%rsp), %r10
movq 0x40(%rsp), %r11
jmp 0x324ef
movq 0x18(%r9), %rdx
andq $-0x4, %rdx
movq %rdx, 0x18(%rsp)
movl $0x1, %edx
movq %rdx, 0x30(%rsp)
movq 0x88(%r13), %r15
testq %r15, %r15
movq %rax, 0x68(%rsp)
movq %r9, 0x58(%rsp)
movq %r15, 0x70(%rsp)
je 0x3252f
movq %r15, %r14
movq 0x18(%rsp), %rdx
cmpb $0x0, (%r14)
jg 0x32545
movq 0x10(%r14), %r14
cmpq %r15, %r14
jne 0x32512
movq $0x0, 0x28(%rsp)
xorl %r9d, %r9d
jmp 0x32558
movq $0x0, 0x28(%rsp)
xorl %r14d, %r14d
xorl %r9d, %r9d
movq 0x18(%rsp), %rdx
jmp 0x32558
movq 0x18(%r14), %rax
andq $-0x4, %rax
movq %rax, 0x28(%rsp)
movl $0x1, %r9d
movl $0x1, 0x3c(%rsp)
movq %rdx, %rax
orq 0x28(%rsp), %rax
je 0x32605
movl $0x1, %r15d
testq %rdx, %rdx
je 0x3261b
movq 0x28(%rsp), %rax
testq %rax, %rax
je 0x3261b
movq %r9, 0x60(%rsp)
movq %rdx, 0x18(%rsp)
leaq 0x60(%rdx), %rdi
leaq 0x60(%rax), %rsi
movl $0x11000e00, %edx       # imm = 0x11000E00
movl $0x11000e00, %ecx       # imm = 0x11000E00
callq 0x32020
testq %rax, %rax
je 0x3262c
leaq 0x5e948(%rip), %rdi     # 0x90f00
leaq 0x18783(%rip), %rsi     # 0x4ad42
movl 0x3c(%rsp), %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0xe2c0
leaq 0x5e92c(%rip), %rax     # 0x90f00
movq %rax, 0x8(%rsp)
movq 0x20(%rsp), %r8
movq 0x50(%rsp), %rcx
leaq 0x1869a(%rip), %rsi     # 0x4ac84
leaq 0x186a3(%rip), %rdi     # 0x4ac94
movq 0x48(%rsp), %r10
movq 0x40(%rsp), %r11
movq 0x60(%rsp), %r9
jmp 0x326e3
movl $0xd, %r15d
xorl %edx, %edx
movq $0x0, 0x28(%rsp)
jmp 0x326e8
leaq 0x18706(%rip), %rax     # 0x4ad28
movq %rax, 0x8(%rsp)
jmp 0x326e8
movq 0x20(%rsp), %r8
movq 0x50(%rsp), %rcx
leaq 0x18647(%rip), %rsi     # 0x4ac84
leaq 0x18650(%rip), %rdi     # 0x4ac94
movq 0x48(%rsp), %r10
movq 0x40(%rsp), %r11
movq 0x68(%rsp), %r9
movq 0x58(%rsp), %r15
movq 0x30(%rsp), %rdx
movsbl (%r15), %eax
cmpl %eax, %edx
jl 0x32684
movq 0x10(%r15), %r15
xorl %edx, %edx
cmpq %r9, %r15
jne 0x3265d
movq $0x0, 0x30(%rsp)
movq $0x0, 0x18(%rsp)
jmp 0x3269c
movslq %edx, %rax
movq 0x18(%r15,%rax,8), %rax
andq $-0x4, %rax
movq %rax, 0x18(%rsp)
incl %edx
movq %rdx, 0x30(%rsp)
movq 0x60(%rsp), %r9
movq %r15, 0x58(%rsp)
movsbl (%r14), %eax
cmpl %eax, %r9d
jl 0x326c8
movq 0x10(%r14), %r14
xorl %r9d, %r9d
cmpq 0x70(%rsp), %r14
jne 0x326a6
movq $0x0, 0x28(%rsp)
jmp 0x326dc
movslq %r9d, %rax
movq 0x18(%r14,%rax,8), %rax
andq $-0x4, %rax
movq %rax, 0x28(%rsp)
incl %r9d
incl 0x3c(%rsp)
xorl %r15d, %r15d
movq 0x18(%rsp), %rdx
testl %r15d, %r15d
je 0x32560
cmpl $0xd, %r15d
jne 0x326fa
xorl %r15d, %r15d
movq 0x10(%rsp), %rdx
testl %r15d, %r15d
movl $0x4, %eax
cmovel %eax, %r15d
movq 0x8(%rsp), %rax
movq %rax, 0x8(%rsp)
movl $0x1, %r14d
cmpl $0x4, %r15d
jne 0x321bf
xorl %r15d, %r15d
movl $0x1, %ebx
movl $0x1, %r14d
movq %rbp, %r13
movq %rdx, %r12
jmp 0x321bf
movl $0x1, %r14d
movq $0x0, 0x8(%rsp)
jmp 0x321bf
cmpl $0x2, %r15d
jne 0x32780
cmpq %r11, %r10
je 0x32766
leaq 0x18577(%rip), %rax     # 0x4acdb
jmp 0x3277b
xorq %rcx, %r8
andq $-0x2043e1e0, %r8       # imm = 0xDFBC1E20
leaq 0x1857d(%rip), %rax     # 0x4acf4
cmoveq %r8, %rax
movq %rax, 0x8(%rsp)
movq 0x8(%rsp), %rax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq