// File: /workspace/github_c_makefile_star2_O1/lucvoo[P]sparse-dev/simplify.c
// Function: eval_op
static pseudo_t eval_op(int op, unsigned size, pseudo_t src1, pseudo_t src2)
{
	/* FIXME! Verify signs and sizes!! */
	long long left = src1->value;
	long long right = src2->value;
	unsigned long long ul, ur;
	long long res, mask, bits;

	mask = 1ULL << (size-1);
	bits = mask | (mask-1);

	if (left & mask)
		left |= ~bits;
	if (right & mask)
		right |= ~bits;
	ul = left & bits;
	ur = right & bits;

	switch (op) {
	case OP_NEG:
		res = -left;
		break;
	case OP_NOT:
		res = ~ul;
		break;

	case OP_ADD:
		res = left + right;
		break;
	case OP_SUB:
		res = left - right;
		break;
	case OP_MUL:
		res = ul * ur;
		break;
	case OP_DIVU:
		if (!ur)
			goto undef;
		res = ul / ur;
		break;
	case OP_DIVS:
		if (!right)
			goto undef;
		if (left == mask && right == -1)
			goto undef;
		res = left / right;
		break;
	case OP_MODU:
		if (!ur)
			goto undef;
		res = ul % ur;
		break;
	case OP_MODS:
		if (!right)
			goto undef;
		if (left == mask && right == -1)
			goto undef;
		res = left % right;
		break;
	case OP_SHL:
		if (ur >= size)
			goto undef;
		res = left << right;
		break;
	case OP_LSR:
		if (ur >= size)
			goto undef;
		res = ul >> ur;
		break;
	case OP_ASR:
		if (ur >= size)
			goto undef;
		res = left >> right;
		break;
       /* Logical */
	case OP_AND:
		res = left & right;
		break;
	case OP_OR:
		res = left | right;
		break;
	case OP_XOR:
		res = left ^ right;
		break;

	/* Binary comparison */
	case OP_SET_EQ:
		res = left == right;
		break;
	case OP_SET_NE:
		res = left != right;
		break;
	case OP_SET_LE:
		res = left <= right;
		break;
	case OP_SET_GE:
		res = left >= right;
		break;
	case OP_SET_LT:
		res = left < right;
		break;
	case OP_SET_GT:
		res = left > right;
		break;
	case OP_SET_B:
		res = ul < ur;
		break;
	case OP_SET_A:
		res = ul > ur;
		break;
	case OP_SET_BE:
		res = ul <= ur;
		break;
	case OP_SET_AE:
		res = ul >= ur;
		break;
	default:
		return NULL;
	}

	// Warning: this should be done with the output size which may
	// be different than the input size used here. But it differs
	// only for compares which are not concerned since only returning
	// 0 or 1 and for casts which are not handled here.
	res &= bits;

	return value_pseudo(res);

undef:
	return NULL;
}

// Assembly:
pushq %rbx
movl %edi, %r9d
movq 0x18(%rdx), %rax
movq 0x18(%rcx), %r8
leal -0x1(%rsi), %edx
movl $0x1, %r11d
movl %edx, %ecx
shlq %cl, %r11
movl %esi, %ecx
negb %cl
movq $-0x1, %r10
shrq %cl, %r10
movzbl %dl, %edx
xorl %ebx, %ebx
btq %rdx, %rax
movq %r10, %rcx
notq %rcx
movq %rcx, %rdi
cmovaeq %rbx, %rdi
btq %rdx, %r8
cmovaeq %rbx, %rcx
addl $-0x8, %r9d
cmpl $0x2a, %r9d
ja 0x28704
orq %rax, %rdi
orq %r8, %rcx
andq %r10, %rax
andq %r10, %r8
leaq 0x1fc65(%rip), %rdx     # 0x48244
movslq (%rdx,%r9,4), %r9
addq %rdx, %r9
jmpq *%r9
addq %rcx, %rdi
jmp 0x2871d
xorl %edi, %edi
cmpq %r8, %rax
setb %dil
jmp 0x2871d
xorl %edi, %edi
cmpq %r8, %rax
seta %dil
jmp 0x2871d
xorl %eax, %eax
cmpq %rcx, %rdi
sete %al
jmp 0x2871a
notq %rax
jmp 0x2871a
andq %rcx, %rdi
jmp 0x2871d
subq %rcx, %rdi
jmp 0x2871d
testq %rcx, %rcx
je 0x28704
cmpq %r11, %rdi
jne 0x2864a
cmpq $-0x1, %rcx
je 0x28704
movq %rdi, %rax
cqto
idivq %rcx
jmp 0x2871a
xorl %eax, %eax
cmpq %rcx, %rdi
setne %al
jmp 0x2871a
xorq %rcx, %rdi
jmp 0x2871d
xorl %edi, %edi
cmpq %r8, %rax
setbe %dil
jmp 0x2871d
testq %r8, %r8
je 0x28704
xorl %edx, %edx
divq %r8
jmp 0x286c4
orq %rcx, %rdi
jmp 0x2871d
testq %r8, %r8
je 0x28704
xorl %edx, %edx
divq %r8
jmp 0x2871a
imulq %rax, %r8
movq %r8, %rdi
jmp 0x2871d
negq %rdi
jmp 0x2871d
testq %rcx, %rcx
je 0x28704
cmpq %r11, %rdi
jne 0x286bc
cmpq $-0x1, %rcx
je 0x28704
movq %rdi, %rax
cqto
idivq %rcx
movq %rdx, %rdi
jmp 0x2871d
movl %esi, %ecx
cmpq %rcx, %r8
jae 0x28704
movl %r8d, %ecx
shrq %cl, %rax
jmp 0x2871a
xorl %eax, %eax
cmpq %rcx, %rdi
setl %al
jmp 0x2871a
xorl %eax, %eax
cmpq %rcx, %rdi
setle %al
jmp 0x2871a
movl %esi, %eax
cmpq %rax, %r8
jae 0x28704
shlq %cl, %rdi
jmp 0x2871d
movl %esi, %eax
cmpq %rax, %r8
jae 0x28704
sarq %cl, %rdi
jmp 0x2871d
xorl %eax, %eax
popq %rbx
retq
xorl %eax, %eax
cmpq %rcx, %rdi
setg %al
jmp 0x2871a
xorl %eax, %eax
cmpq %rcx, %rdi
setge %al
movq %rax, %rdi
andq %r10, %rdi
popq %rbx
jmp 0x136d3
xorl %edi, %edi
cmpq %r8, %rax
setae %dil
jmp 0x2871d