// File: /workspace/github_c_makefile_star2_O0/lucvoo[P]sparse-dev/linearize.c
// Function: linearize_expression
static pseudo_t linearize_expression(struct entrypoint *ep, struct expression *expr)
{
	if (!expr || !valid_type(expr->ctype))
		return VOID;

	current_pos = expr->pos;
	switch (expr->type) {
	case EXPR_SYMBOL:
		linearize_one_symbol(ep, expr->symbol);
		return add_symbol_address(ep, expr);

	case EXPR_VALUE:
		return value_pseudo(expr->value);

	case EXPR_STRING:
	case EXPR_LABEL:
		return add_setval(ep, expr->ctype, expr);

	case EXPR_FVALUE:
		return add_setfval(ep, expr->ctype, expr->fvalue);

	case EXPR_STATEMENT:
		return linearize_statement(ep, expr->statement);

	case EXPR_CALL:
		return linearize_call_expression(ep, expr);

	case EXPR_BINOP:
		if (expr->op == SPECIAL_LOGICAL_AND || expr->op == SPECIAL_LOGICAL_OR)
			return linearize_binop_bool(ep, expr);
		return linearize_binop(ep, expr);

	case EXPR_LOGICAL:
		return linearize_logical(ep, expr);

	case EXPR_COMPARE:
		return  linearize_compare(ep, expr);

	case EXPR_SELECT:
		return	linearize_select(ep, expr);

	case EXPR_CONDITIONAL:
		if (!expr->cond_true)
			return linearize_short_conditional(ep, expr, expr->conditional, expr->cond_false);

		return  linearize_conditional(ep, expr, expr->conditional,
					      expr->cond_true, expr->cond_false);

	case EXPR_COMMA:
		linearize_expression(ep, expr->left);
		return linearize_expression(ep, expr->right);

	case EXPR_ASSIGNMENT:
		return linearize_assignment(ep, expr);

	case EXPR_PREOP:
		return linearize_preop(ep, expr);

	case EXPR_POSTOP:
		return linearize_postop(ep, expr);

	case EXPR_CAST:
	case EXPR_FORCE_CAST:
	case EXPR_IMPLIED_CAST:
		return linearize_cast(ep, expr);
	
	case EXPR_SLICE:
		return linearize_slice(ep, expr);

	case EXPR_INITIALIZER:
	case EXPR_POS:
		warning(expr->pos, "unexpected initializer expression (%d %d)", expr->type, expr->op);
		return VOID;
	default: 
		warning(expr->pos, "unknown expression (%d %d)", expr->type, expr->op);
		return VOID;
	}
	return VOID;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x1bbb9
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x1bf60
cmpl $0x0, %eax
jne 0x1bbc9
leaq 0x701f0(%rip), %rax     # 0x8bdb0
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x71570(%rip)     # 0x8d148
movq -0x18(%rbp), %rax
movzbl (%rax), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x20(%rbp)
subl $0x1c, %eax
ja 0x1be61
movq -0x20(%rbp), %rax
leaq 0x46e1d(%rip), %rcx     # 0x62a18
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rsi
callq 0x1bf90
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x1c0c0
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x1a390
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rsi
movq -0x18(%rbp), %rdx
callq 0x1c150
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rsi
fldt 0x20(%rax)
movq %rsp, %rax
fstpt (%rax)
callq 0x1c1c0
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rsi
callq 0x1c230
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x1c750
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x18(%rbp), %rax
cmpl $0x10c, 0x4(%rax)       # imm = 0x10C
je 0x1bccb
movq -0x18(%rbp), %rax
cmpl $0x10e, 0x4(%rax)       # imm = 0x10E
jne 0x1bce1
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x1cbe0
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x1cca0
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x1cd40
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x1cee0
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x1cf80
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x18(%rbp), %rax
cmpq $0x0, 0x28(%rax)
jne 0x1bd6a
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rdx
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rcx
callq 0x1d070
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rdx
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rcx
movq -0x18(%rbp), %rax
movq 0x30(%rax), %r8
callq 0x1d190
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rsi
callq 0x1bb90
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rsi
callq 0x1bb90
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x1d2f0
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x1d460
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x1d4e0
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x1d510
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x1d580
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x18(%rbp), %rax
movq -0x18(%rbp), %rcx
movl (%rcx), %edx
andl $0xff, %edx
movq -0x18(%rbp), %rcx
movl 0x4(%rcx), %ecx
movq 0x8(%rax), %rdi
leaq 0x47b84(%rip), %rsi     # 0x639d1
movb $0x0, %al
callq 0x16d80
leaq 0x6ff55(%rip), %rax     # 0x8bdb0
movq %rax, -0x8(%rbp)
jmp 0x1be95
movq -0x18(%rbp), %rax
movq -0x18(%rbp), %rcx
movl (%rcx), %edx
andl $0xff, %edx
movq -0x18(%rbp), %rcx
movl 0x4(%rcx), %ecx
movq 0x8(%rax), %rdi
leaq 0x47b78(%rip), %rsi     # 0x639fb
movb $0x0, %al
callq 0x16d80
leaq 0x6ff1f(%rip), %rax     # 0x8bdb0
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x30, %rsp
popq %rbp
retq
nop