// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0xd0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
movl $0x1, -0x4c(%rbp)
movl $0x1, -0x50(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
orq -0x20(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
orq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x40(%rbp), %rax
movq 0x60(%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x48(%rbp), %rax
movq 0x60(%rax), %rax
movq %rax, -0x70(%rbp)
cmpl $0x0, -0x4c(%rbp)
je 0x4ae4f
cmpq $0x0, -0x40(%rbp)
je 0x4ae48
movq -0x40(%rbp), %rax
movl (%rax), %eax
andl $0xff, %eax
cmpl $0x4, %eax
je 0x4ae48
movq -0x40(%rbp), %rax
movq 0x68(%rax), %rax
orq -0x20(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x40(%rbp), %rax
movq -0x40(%rbp), %rcx
movq 0x80(%rcx), %rdx
movq 0x4(%rax), %rdi
leaq -0x30(%rbp), %rsi
callq 0x4b5e0
movl $0x0, -0x4c(%rbp)
cmpl $0x0, -0x50(%rbp)
je 0x4ae9f
cmpq $0x0, -0x48(%rbp)
je 0x4ae98
movq -0x48(%rbp), %rax
movl (%rax), %eax
andl $0xff, %eax
cmpl $0x4, %eax
je 0x4ae98
movq -0x48(%rbp), %rax
movq 0x68(%rax), %rax
orq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x48(%rbp), %rax
movq -0x48(%rbp), %rcx
movq 0x80(%rcx), %rdx
movq 0x4(%rax), %rdi
leaq -0x38(%rbp), %rsi
callq 0x4b5e0
movl $0x0, -0x50(%rbp)
movq -0x40(%rbp), %rax
cmpq -0x48(%rbp), %rax
jne 0x4aeae
jmp 0x4b58b
cmpq $0x0, -0x40(%rbp)
je 0x4aebc
cmpq $0x0, -0x48(%rbp)
jne 0x4aecc
leaq 0x20a51(%rip), %rax     # 0x6b914
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
movq -0x40(%rbp), %rax
movl (%rax), %eax
andl $0xff, %eax
cmpl $0x3, %eax
je 0x4aeec
movq -0x40(%rbp), %rax
movl (%rax), %eax
andl $0xff, %eax
cmpl $0x9, %eax
jne 0x4af17
movq -0x68(%rbp), %rax
movq %rax, -0x40(%rbp)
movl $0x1, -0x4c(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0x4af12
leaq 0x20a1b(%rip), %rax     # 0x6b924
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
jmp 0x4ade7
movq -0x48(%rbp), %rax
movl (%rax), %eax
andl $0xff, %eax
cmpl $0x3, %eax
je 0x4af37
movq -0x48(%rbp), %rax
movl (%rax), %eax
andl $0xff, %eax
cmpl $0x9, %eax
jne 0x4af62
movq -0x70(%rbp), %rax
movq %rax, -0x48(%rbp)
movl $0x1, -0x50(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x4af5d
leaq 0x209d0(%rip), %rax     # 0x6b924
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
jmp 0x4ade7
movl $0x1, -0x50(%rbp)
movl $0x1, -0x4c(%rbp)
movq -0x40(%rbp), %rax
movl (%rax), %eax
andl $0xff, %eax
movl %eax, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
movq -0x48(%rbp), %rcx
movl (%rcx), %ecx
andl $0xff, %ecx
cmpl %ecx, %eax
je 0x4afa1
leaq 0x20996(%rip), %rax     # 0x6b92e
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
movl -0x5c(%rbp), %eax
addl $-0x2, %eax
movl %eax, %ecx
movq %rcx, -0xc8(%rbp)
subl $0xb, %eax
ja 0x4afcc
movq -0xc8(%rbp), %rax
leaq 0x20685(%rip), %rcx     # 0x6b648
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x40(%rbp), %rax
movl -0x5c(%rbp), %edx
movq 0x4(%rax), %rdi
leaq 0x20965(%rip), %rsi     # 0x6b943
movb $0x0, %al
callq 0x16f90
leaq 0x20938(%rip), %rax     # 0x6b924
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
leaq 0x20932(%rip), %rax     # 0x6b92e
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
movq -0x40(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x48(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jne 0x4b024
movq $0x0, -0x8(%rbp)
jmp 0x4b5d1
leaq 0x20903(%rip), %rax     # 0x6b92e
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
jmp 0x4b576
movq -0x30(%rbp), %rax
cmpq -0x38(%rbp), %rax
je 0x4b053
leaq 0x20921(%rip), %rax     # 0x6b96b
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
movq -0x20(%rbp), %rax
xorq -0x28(%rbp), %rax
andq $-0x204381e0, %rax      # imm = 0xDFBC7E20
andq $-0xe001, %rax          # imm = 0xFFFF1FFF
cmpq $0x0, %rax
je 0x4b07d
leaq 0x20910(%rip), %rax     # 0x6b984
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
movq -0x40(%rbp), %rdi
callq 0x40260
movq %rax, -0x68(%rbp)
movq -0x48(%rbp), %rdi
callq 0x40260
movq %rax, -0x70(%rbp)
movq -0x40(%rbp), %rax
movq 0x68(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x40(%rbp), %rax
movq 0x80(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x48(%rbp), %rax
movq 0x68(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x48(%rbp), %rax
movq 0x80(%rax), %rax
movq %rax, -0x38(%rbp)
jmp 0x4b576
movq -0x30(%rbp), %rax
cmpq -0x38(%rbp), %rax
je 0x4b0ec
leaq 0x20888(%rip), %rax     # 0x6b96b
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
movq -0x20(%rbp), %rax
xorq -0x28(%rbp), %rax
andq $-0x204381e0, %rax      # imm = 0xDFBC7E20
andq $-0xe001, %rax          # imm = 0xFFFF1FFF
cmpq $0x0, %rax
je 0x4b116
leaq 0x20877(%rip), %rax     # 0x6b984
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
movq -0x40(%rbp), %rax
movq 0x68(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x40(%rbp), %rax
movq 0x80(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x48(%rbp), %rax
movq 0x68(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x48(%rbp), %rax
movq 0x80(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x40(%rbp), %rax
movl 0x54(%rax), %eax
shrl $0x9, %eax
andl $0x1, %eax
movq -0x48(%rbp), %rcx
movl 0x54(%rcx), %ecx
shrl $0x9, %ecx
andl $0x1, %ecx
cmpl %ecx, %eax
je 0x4b17a
leaq 0x20827(%rip), %rax     # 0x6b998
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
movq -0x40(%rbp), %rdi
callq 0x4b650
movq -0x48(%rbp), %rdi
callq 0x4b650
movq -0x40(%rbp), %rax
movq 0x88(%rax), %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
movq %rax, -0x98(%rbp)
movl $0x0, -0x9c(%rbp)
movq $0x0, -0x78(%rbp)
cmpq $0x0, -0x90(%rbp)
je 0x4b244
jmp 0x4b1ca
movl -0x9c(%rbp), %eax
movq -0x98(%rbp), %rcx
movw (%rcx), %cx
shlw $0x8, %cx
sarw $0x8, %cx
movswl %cx, %ecx
cmpl %ecx, %eax
jge 0x4b215
movq -0x98(%rbp), %rax
movslq -0x9c(%rbp), %rcx
movq 0x18(%rax,%rcx,8), %rax
andq $-0x4, %rax
movq %rax, -0x78(%rbp)
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0x4b242
movq $0x0, -0x78(%rbp)
movl $0x0, -0x9c(%rbp)
movq -0x98(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x98(%rbp)
cmpq -0x90(%rbp), %rax
jne 0x4b1ca
jmp 0x4b244
jmp 0x4b246
movq -0x48(%rbp), %rax
movq 0x88(%rax), %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rax
movq %rax, -0xb0(%rbp)
movl $0x0, -0xb4(%rbp)
movq $0x0, -0x80(%rbp)
cmpq $0x0, -0xa8(%rbp)
je 0x4b2fe
jmp 0x4b284
movl -0xb4(%rbp), %eax
movq -0xb0(%rbp), %rcx
movw (%rcx), %cx
shlw $0x8, %cx
sarw $0x8, %cx
movswl %cx, %ecx
cmpl %ecx, %eax
jge 0x4b2cf
movq -0xb0(%rbp), %rax
movslq -0xb4(%rbp), %rcx
movq 0x18(%rax,%rcx,8), %rax
andq $-0x4, %rax
movq %rax, -0x80(%rbp)
movl -0xb4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb4(%rbp)
jmp 0x4b2fc
movq $0x0, -0x80(%rbp)
movl $0x0, -0xb4(%rbp)
movq -0xb0(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0xb0(%rbp)
cmpq -0xa8(%rbp), %rax
jne 0x4b284
jmp 0x4b2fe
movl $0x1, -0x84(%rbp)
cmpq $0x0, -0x78(%rbp)
jne 0x4b31b
cmpq $0x0, -0x80(%rbp)
jne 0x4b31b
jmp 0x4b4bb
cmpq $0x0, -0x78(%rbp)
je 0x4b329
cmpq $0x0, -0x80(%rbp)
jne 0x4b339
leaq 0x20688(%rip), %rax     # 0x6b9b8
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
movq -0x78(%rbp), %rdi
addq $0x48, %rdi
addq $0x18, %rdi
movq -0x80(%rbp), %rsi
addq $0x48, %rsi
addq $0x18, %rsi
movl $0x11000e00, %ecx       # imm = 0x11000E00
movq %rcx, %rdx
callq 0x4ad70
movq %rax, -0xc0(%rbp)
cmpq $0x0, -0xc0(%rbp)
je 0x4b3a1
movl -0x84(%rbp), %edx
movq -0xc0(%rbp), %rcx
leaq 0x6af5d(%rip), %rdi     # 0xb62e0
leaq 0x20648(%rip), %rsi     # 0x6b9d2
movb $0x0, %al
callq 0x112c0
leaq 0x6af48(%rip), %rax     # 0xb62e0
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
cmpq $0x0, -0x78(%rbp)
je 0x4b424
jmp 0x4b3aa
movl -0x9c(%rbp), %eax
movq -0x98(%rbp), %rcx
movw (%rcx), %cx
shlw $0x8, %cx
sarw $0x8, %cx
movswl %cx, %ecx
cmpl %ecx, %eax
jge 0x4b3f5
movq -0x98(%rbp), %rax
movslq -0x9c(%rbp), %rcx
movq 0x18(%rax,%rcx,8), %rax
andq $-0x4, %rax
movq %rax, -0x78(%rbp)
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0x4b422
movq $0x0, -0x78(%rbp)
movl $0x0, -0x9c(%rbp)
movq -0x98(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x98(%rbp)
cmpq -0x90(%rbp), %rax
jne 0x4b3aa
jmp 0x4b424
cmpq $0x0, -0x80(%rbp)
je 0x4b4a7
jmp 0x4b42d
movl -0xb4(%rbp), %eax
movq -0xb0(%rbp), %rcx
movw (%rcx), %cx
shlw $0x8, %cx
sarw $0x8, %cx
movswl %cx, %ecx
cmpl %ecx, %eax
jge 0x4b478
movq -0xb0(%rbp), %rax
movslq -0xb4(%rbp), %rcx
movq 0x18(%rax,%rcx,8), %rax
andq $-0x4, %rax
movq %rax, -0x80(%rbp)
movl -0xb4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb4(%rbp)
jmp 0x4b4a5
movq $0x0, -0x80(%rbp)
movl $0x0, -0xb4(%rbp)
movq -0xb0(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0xb0(%rbp)
cmpq -0xa8(%rbp), %rax
jne 0x4b42d
jmp 0x4b4a7
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0x4b308
jmp 0x4b4bd
jmp 0x4b4bf
jmp 0x4b576
movq -0x30(%rbp), %rax
cmpq -0x38(%rbp), %rax
je 0x4b4de
leaq 0x20496(%rip), %rax     # 0x6b96b
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
movq -0x68(%rbp), %rax
cmpq -0x70(%rbp), %rax
je 0x4b4f8
leaq 0x2043f(%rip), %rax     # 0x6b92e
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
movq -0x40(%rbp), %rax
movl 0x54(%rax), %eax
shll $0x6, %eax
sarl $0x1d, %eax
movq -0x48(%rbp), %rcx
movl 0x54(%rcx), %ecx
shll $0x6, %ecx
sarl $0x1d, %ecx
cmpl %ecx, %eax
je 0x4b526
leaq 0x204d3(%rip), %rax     # 0x6b9f0
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
movq -0x20(%rbp), %rax
xorq -0x28(%rbp), %rax
andq $-0x204381e0, %rax      # imm = 0xDFBC7E20
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x58(%rbp)
jne 0x4b54c
movq $0x0, -0x8(%rbp)
jmp 0x4b5d1
movq -0x58(%rbp), %rax
andq $-0xe001, %rax          # imm = 0xFFFF1FFF
cmpq $0x0, %rax
je 0x4b569
leaq 0x20421(%rip), %rax     # 0x6b984
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
leaq 0x20495(%rip), %rax     # 0x6ba05
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
movq -0x68(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x70(%rbp), %rax
movq %rax, -0x48(%rbp)
jmp 0x4ade7
movq -0x30(%rbp), %rax
cmpq -0x38(%rbp), %rax
je 0x4b5a2
leaq 0x203cf(%rip), %rax     # 0x6b96b
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
movq -0x20(%rbp), %rax
xorq -0x28(%rbp), %rax
andq $-0x204381e0, %rax      # imm = 0xDFBC7E20
andq $-0xe001, %rax          # imm = 0xFFFF1FFF
cmpq $0x0, %rax
je 0x4b5c9
leaq 0x203c1(%rip), %rax     # 0x6b984
movq %rax, -0x8(%rbp)
jmp 0x4b5d1
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xd0, %rsp
popq %rbp
retq
nop