// File: /workspace/github_c_makefile_star2_O0/lucvoo[P]sparse-dev/evaluate.c
// Function: evaluate_binop
static struct symbol *evaluate_binop(struct expression *expr)
{
	struct symbol *ltype, *rtype, *ctype;
	int lclass = classify_type(expr->left->ctype, &ltype);
	int rclass = classify_type(expr->right->ctype, &rtype);
	int op = expr->op;

	/* number op number */
	if (lclass & rclass & TYPE_NUM) {
		expr->flags = expr->left->flags & expr->right->flags;
		expr->flags &= ~CEF_CONST_MASK;

		if ((lclass | rclass) & TYPE_FLOAT) {
			switch (op) {
			case '+': case '-': case '*': case '/':
				break;
			default:
				return bad_expr_type(expr);
			}
		}

		if (op == SPECIAL_LEFTSHIFT || op == SPECIAL_RIGHTSHIFT) {
			// shifts do integer promotions, but that's it.
			unrestrict(expr->left, lclass, &ltype);
			unrestrict(expr->right, rclass, &rtype);
			ctype = ltype = integer_promotion(ltype);
			rtype = integer_promotion(rtype);
		} else {
			// The rest do usual conversions
			const unsigned left_not  = expr->left->type == EXPR_PREOP
			                           && expr->left->op == '!';
			const unsigned right_not = expr->right->type == EXPR_PREOP
			                           && expr->right->op == '!';
			if ((op == '&' || op == '|') && (left_not || right_not))
				warning(expr->pos, "dubious: %sx %c %sy",
				        left_not ? "!" : "",
					op,
					right_not ? "!" : "");

			ltype = usual_conversions(op, expr->left, expr->right,
						  lclass, rclass, ltype, rtype);
			ctype = rtype = ltype;
		}

		expr->left = cast_to(expr->left, ltype);
		expr->right = cast_to(expr->right, rtype);
		expr->ctype = ctype;
		return ctype;
	}

	/* pointer (+|-) integer */
	if (lclass & TYPE_PTR && is_int(rclass) && (op == '+' || op == '-')) {
		unrestrict(expr->right, rclass, &rtype);
		return evaluate_ptr_add(expr, rtype);
	}

	/* integer + pointer */
	if (rclass & TYPE_PTR && is_int(lclass) && op == '+') {
		struct expression *index = expr->left;
		unrestrict(index, lclass, &ltype);
		expr->left = expr->right;
		expr->right = index;
		return evaluate_ptr_add(expr, ltype);
	}

	/* pointer - pointer */
	if (lclass & rclass & TYPE_PTR && expr->op == '-')
		return evaluate_ptr_sub(expr);

	return bad_expr_type(expr);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x10(%rax), %rdi
leaq -0x18(%rbp), %rsi
callq 0x4bf20
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x10(%rax), %rdi
leaq -0x20(%rbp), %rsi
callq 0x4bf20
movl %eax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x34(%rbp)
movl -0x2c(%rbp), %eax
andl -0x30(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x4cc6f
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movl (%rax), %edx
shrl $0x8, %edx
andl $0xff, %edx
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movl (%rax), %eax
shrl $0x8, %eax
andl $0xff, %eax
andl %eax, %edx
movq -0x10(%rbp), %rax
movl (%rax), %ecx
andl $0xff, %edx
shll $0x8, %edx
andl $0xffff00ff, %ecx       # imm = 0xFFFF00FF
orl %edx, %ecx
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movl (%rax), %edx
shrl $0x8, %edx
andl $0xff, %edx
andl $-0xc, %edx
movl (%rax), %ecx
andl $0xff, %edx
shll $0x8, %edx
andl $0xffff00ff, %ecx       # imm = 0xFFFF00FF
orl %edx, %ecx
movl %ecx, (%rax)
movl -0x2c(%rbp), %eax
orl -0x30(%rbp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x4cab7
movl -0x34(%rbp), %eax
movl %eax, -0x4c(%rbp)
addl $-0x2a, %eax
subl $0x2, %eax
jb 0x4caa1
jmp 0x4ca8d
movl -0x4c(%rbp), %eax
subl $0x2d, %eax
je 0x4caa1
jmp 0x4ca97
movl -0x4c(%rbp), %eax
subl $0x2f, %eax
jne 0x4caa3
jmp 0x4caa1
jmp 0x4cab5
movq -0x10(%rbp), %rdi
callq 0x51ed0
movq %rax, -0x8(%rbp)
jmp 0x4cd56
jmp 0x4cab7
cmpl $0x112, -0x34(%rbp)     # imm = 0x112
je 0x4cac9
cmpl $0x113, -0x34(%rbp)     # imm = 0x113
jne 0x4cb14
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movl -0x2c(%rbp), %esi
leaq -0x18(%rbp), %rdx
callq 0x51240
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movl -0x30(%rbp), %esi
leaq -0x20(%rbp), %rdx
callq 0x51240
movq -0x18(%rbp), %rdi
callq 0x4c110
movq %rax, -0x18(%rbp)
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rdi
callq 0x4c110
movq %rax, -0x20(%rbp)
jmp 0x4cc1e
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movl (%rax), %ecx
andl $0xff, %ecx
xorl %eax, %eax
cmpl $0x9, %ecx
movb %al, -0x4d(%rbp)
jne 0x4cb40
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
cmpl $0x21, 0x4(%rax)
sete %al
movb %al, -0x4d(%rbp)
movb -0x4d(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x38(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movl (%rax), %ecx
andl $0xff, %ecx
xorl %eax, %eax
cmpl $0x9, %ecx
movb %al, -0x4e(%rbp)
jne 0x4cb77
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
cmpl $0x21, 0x4(%rax)
sete %al
movb %al, -0x4e(%rbp)
movb -0x4e(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x3c(%rbp)
cmpl $0x26, -0x34(%rbp)
je 0x4cb8e
cmpl $0x7c, -0x34(%rbp)
jne 0x4cbe3
cmpl $0x0, -0x38(%rbp)
jne 0x4cb9a
cmpl $0x0, -0x3c(%rbp)
je 0x4cbe3
movq -0x10(%rbp), %rax
movl -0x38(%rbp), %esi
leaq 0x15c81(%rip), %rdx     # 0x62829
leaq 0x1b9e1(%rip), %rcx     # 0x68590
cmpl $0x0, %esi
cmovneq %rcx, %rdx
movl -0x34(%rbp), %ecx
movl -0x3c(%rbp), %edi
leaq 0x15c66(%rip), %r8      # 0x62829
leaq 0x1b9c6(%rip), %rsi     # 0x68590
cmpl $0x0, %edi
cmovneq %rsi, %r8
movq 0x8(%rax), %rdi
leaq 0x1f105(%rip), %rsi     # 0x6bce1
movb $0x0, %al
callq 0x16d80
movl -0x34(%rbp), %edi
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rsi
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdx
movl -0x2c(%rbp), %ecx
movl -0x30(%rbp), %r8d
movq -0x18(%rbp), %r9
movq -0x20(%rbp), %rax
movq %rax, (%rsp)
callq 0x50e50
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x20(%rbp)
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x18(%rbp), %rsi
callq 0x4c020
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x20(%rbp), %rsi
callq 0x4c020
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x28(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x28(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x4cd56
movl -0x2c(%rbp), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x4ccbb
movl -0x30(%rbp), %eax
andl $0x9, %eax
cmpl $0x1, %eax
jne 0x4ccbb
cmpl $0x2b, -0x34(%rbp)
je 0x4cc91
cmpl $0x2d, -0x34(%rbp)
jne 0x4ccbb
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movl -0x30(%rbp), %esi
leaq -0x20(%rbp), %rdx
callq 0x51240
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x52060
movq %rax, -0x8(%rbp)
jmp 0x4cd56
movl -0x30(%rbp), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x4cd22
movl -0x2c(%rbp), %eax
andl $0x9, %eax
cmpl $0x1, %eax
jne 0x4cd22
cmpl $0x2b, -0x34(%rbp)
jne 0x4cd22
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
movl -0x2c(%rbp), %esi
leaq -0x18(%rbp), %rdx
callq 0x51240
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x48(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x52060
movq %rax, -0x8(%rbp)
jmp 0x4cd56
movl -0x2c(%rbp), %eax
andl -0x30(%rbp), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x4cd49
movq -0x10(%rbp), %rax
cmpl $0x2d, 0x4(%rax)
jne 0x4cd49
movq -0x10(%rbp), %rdi
callq 0x52380
movq %rax, -0x8(%rbp)
jmp 0x4cd56
movq -0x10(%rbp), %rdi
callq 0x51ed0
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x60, %rsp
popq %rbp
retq