// File: /workspace/github_c_makefile_star2_O3/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
movq %rcx, %r8
movl %edi, %eax
leal -0x1(%rsi), %edi
movl $0x1, %r10d
movl %edi, %ecx
shlq %cl, %r10
movl %esi, %ecx
negb %cl
movq $-0x1, %r9
shrq %cl, %r9
movzbl %dil, %r11d
xorl %ebx, %ebx
btq %r11, %rdx
movq %r9, %rcx
notq %rcx
movq %rcx, %rdi
cmovaeq %rbx, %rdi
btq %r11, %r8
cmovaeq %rbx, %rcx
addl $-0x8, %eax
cmpl $0x2a, %eax
ja 0x28433
orq %rdx, %rdi
orq %r8, %rcx
andq %r9, %rdx
andq %r9, %r8
leaq 0x1eeb8(%rip), %r11     # 0x471c4
movslq (%r11,%rax,4), %rax
addq %r11, %rax
jmpq *%rax
addq %rcx, %rdi
jmp 0x2844c
xorl %edi, %edi
cmpq %r8, %rdx
setb %dil
jmp 0x2844c
xorl %edi, %edi
cmpq %r8, %rdx
seta %dil
jmp 0x2844c
xorl %eax, %eax
cmpq %rcx, %rdi
sete %al
jmp 0x28449
notq %rdx
jmp 0x28402
andq %rcx, %rdi
jmp 0x2844c
subq %rcx, %rdi
jmp 0x2844c
testq %rcx, %rcx
je 0x28433
cmpq %r10, %rdi
jne 0x28376
cmpq $-0x1, %rcx
je 0x28433
movq %rdi, %rax
cqto
idivq %rcx
jmp 0x28449
xorl %eax, %eax
cmpq %rcx, %rdi
setne %al
jmp 0x28449
xorq %rcx, %rdi
jmp 0x2844c
xorl %edi, %edi
cmpq %r8, %rdx
setbe %dil
jmp 0x2844c
testq %r8, %r8
je 0x28433
movq %rdx, %rax
xorl %edx, %edx
divq %r8
jmp 0x28402
orq %rcx, %rdi
jmp 0x2844c
testq %r8, %r8
je 0x28433
movq %rdx, %rax
xorl %edx, %edx
divq %r8
jmp 0x28449
imulq %r8, %rdx
jmp 0x28402
negq %rdi
jmp 0x2844c
testq %rcx, %rcx
je 0x28433
cmpq %r10, %rdi
jne 0x283eb
cmpq $-0x1, %rcx
je 0x28433
movq %rdi, %rax
cqto
idivq %rcx
jmp 0x28402
movl %esi, %eax
cmpq %rax, %r8
jae 0x28433
movl %r8d, %ecx
shrq %cl, %rdx
movq %rdx, %rdi
jmp 0x2844c
xorl %eax, %eax
cmpq %rcx, %rdi
setl %al
jmp 0x28449
xorl %eax, %eax
cmpq %rcx, %rdi
setle %al
jmp 0x28449
movl %esi, %eax
cmpq %rax, %r8
jae 0x28433
shlq %cl, %rdi
jmp 0x2844c
movl %esi, %eax
cmpq %rax, %r8
jae 0x28433
sarq %cl, %rdi
jmp 0x2844c
xorl %eax, %eax
popq %rbx
retq
xorl %eax, %eax
cmpq %rcx, %rdi
setg %al
jmp 0x28449
xorl %eax, %eax
cmpq %rcx, %rdi
setge %al
movq %rax, %rdi
andq %r9, %rdi
popq %rbx
jmp 0x13745
xorl %edi, %edi
cmpq %r8, %rdx
setae %dil
jmp 0x2844c