// File: /workspace/github_c_makefile_star2_O0/lucvoo[P]sparse-dev/linearize.c
// Function: linearize_switch
static pseudo_t linearize_switch(struct entrypoint *ep, struct statement *stmt)
{
	struct symbol *sym;
	struct instruction *switch_ins;
	struct basic_block *switch_end = alloc_basic_block(ep, stmt->pos);
	struct basic_block *active, *default_case;
	struct expression *expr = stmt->switch_expression;
	struct multijmp *jmp;
	pseudo_t pseudo;

	if (!expr || !expr->ctype)
		return VOID;
	pseudo = linearize_expression(ep, expr);
	active = ep->active;
	if (!active) {
		active = alloc_basic_block(ep, stmt->pos);
		set_activeblock(ep, active);
	}

	switch_ins = alloc_typed_instruction(OP_SWITCH, expr->ctype);
	use_pseudo(switch_ins, pseudo, &switch_ins->cond);
	add_one_insn(ep, switch_ins);
	finish_block(ep);

	default_case = NULL;
	FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) {
		struct statement *case_stmt = sym->stmt;
		struct basic_block *bb_case = get_bound_block(ep, sym);

		if (!case_stmt->case_expression) {
			default_case = bb_case;
			continue;
		} else if (case_stmt->case_expression->type != EXPR_VALUE) {
			continue;
		} else {
			struct expression *case_to = case_stmt->case_to;
			long long begin, end;

			begin = end = case_stmt->case_expression->value;
			if (case_to && case_to->type == EXPR_VALUE)
				end = case_to->value;
			if (begin > end)
				jmp = alloc_multijmp(bb_case, end, begin);
			else
				jmp = alloc_multijmp(bb_case, begin, end);

		}
		add_multijmp(&switch_ins->multijmp_list, jmp);
		add_bb(&bb_case->parents, active);
		add_bb(&active->children, bb_case);
	} END_FOR_EACH_PTR(sym);

	bind_label(stmt->switch_break, switch_end, stmt->pos);

	/* And linearize the actual statement */
	linearize_statement(ep, stmt->switch_statement);
	set_activeblock(ep, switch_end);

	if (!default_case)
		default_case = switch_end;

	jmp = alloc_multijmp(default_case, 1, 0);
	add_multijmp(&switch_ins->multijmp_list, jmp);
	add_bb(&default_case->parents, active);
	add_bb(&active->children, default_case);
	sort_switch_cases(switch_ins);

	return VOID;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x4(%rax), %rsi
callq 0x1b110
movq %rax, -0x30(%rbp)
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0x1e876
movq -0x48(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x1e886
leaq 0x6d533(%rip), %rax     # 0x8bdb0
movq %rax, -0x8(%rbp)
jmp 0x1eba3
movq -0x10(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x1bb90
movq %rax, -0x58(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jne 0x1e8cc
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x4(%rax), %rsi
callq 0x1b110
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x1b170
movq -0x48(%rbp), %rax
movq 0x10(%rax), %rsi
movl $0x5, %edi
callq 0x1a240
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
movq -0x58(%rbp), %rsi
movq -0x28(%rbp), %rdx
addq $0x30, %rdx
callq 0x1a290
movq -0x10(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x1b5b0
movq -0x10(%rbp), %rdi
callq 0x1e3f0
movq $0x0, -0x40(%rbp)
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x98(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x70(%rbp)
cmpq $0x0, -0x60(%rbp)
jne 0x1e944
jmp 0x1eafc
jmp 0x1e946
movl $0x0, -0x74(%rbp)
movl -0x74(%rbp), %eax
movq -0x68(%rbp), %rcx
movw (%rcx), %cx
shlw $0x8, %cx
sarw $0x8, %cx
movswl %cx, %ecx
cmpl %ecx, %eax
jge 0x1eae4
movq -0x68(%rbp), %rax
movslq -0x74(%rbp), %rcx
movq 0x18(%rax,%rcx,8), %rax
movq %rax, -0x20(%rbp)
movq -0x68(%rbp), %rax
movw (%rax), %ax
sarw $0x8, %ax
cwtl
cmpl $0x0, %eax
je 0x1e998
cmpq $0x0, -0x20(%rbp)
jne 0x1e998
jmp 0x1ead6
movq -0x20(%rbp), %rax
movq 0x90(%rax), %rax
movq %rax, -0x80(%rbp)
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x1e310
movq %rax, -0x88(%rbp)
movq -0x80(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x1e9d6
movq -0x88(%rbp), %rax
movq %rax, -0x40(%rbp)
jmp 0x1ead6
movq -0x80(%rbp), %rax
movq 0x10(%rax), %rax
movl (%rax), %eax
andl $0xff, %eax
cmpl $0x1, %eax
je 0x1e9ef
jmp 0x1ead6
movq -0x80(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x90(%rbp)
movq -0x80(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x20(%rax), %rax
movq %rax, -0xa0(%rbp)
movq %rax, -0x98(%rbp)
cmpq $0x0, -0x90(%rbp)
je 0x1ea47
movq -0x90(%rbp), %rax
movl (%rax), %eax
andl $0xff, %eax
cmpl $0x1, %eax
jne 0x1ea47
movq -0x90(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0xa0(%rbp)
movq -0x98(%rbp), %rax
cmpq -0xa0(%rbp), %rax
jle 0x1ea77
movq -0x88(%rbp), %rdi
movq -0xa0(%rbp), %rsi
movq -0x98(%rbp), %rdx
callq 0x1e370
movq %rax, -0x50(%rbp)
jmp 0x1ea95
movq -0x88(%rbp), %rdi
movq -0x98(%rbp), %rsi
movq -0xa0(%rbp), %rdx
callq 0x1e370
movq %rax, -0x50(%rbp)
jmp 0x1ea97
jmp 0x1ea99
movq -0x28(%rbp), %rdi
addq $0x30, %rdi
addq $0x8, %rdi
movq -0x50(%rbp), %rsi
callq 0x1e3c0
movq -0x88(%rbp), %rdi
addq $0x18, %rdi
movq -0x38(%rbp), %rsi
callq 0x1b9f0
movq -0x38(%rbp), %rdi
addq $0x20, %rdi
movq -0x88(%rbp), %rsi
callq 0x1b9f0
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0x1e94d
jmp 0x1eae6
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x68(%rbp)
cmpq -0x60(%rbp), %rax
jne 0x1e946
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x30(%rbp), %rsi
movq -0x18(%rbp), %rax
movq 0x4(%rax), %rdx
callq 0x1f3f0
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rsi
callq 0x1c230
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x1b170
cmpq $0x0, -0x40(%rbp)
jne 0x1eb42
movq -0x30(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
movl $0x1, %esi
xorl %eax, %eax
movl %eax, %edx
callq 0x1e370
movq %rax, -0x50(%rbp)
movq -0x28(%rbp), %rdi
addq $0x30, %rdi
addq $0x8, %rdi
movq -0x50(%rbp), %rsi
callq 0x1e3c0
movq -0x40(%rbp), %rdi
addq $0x18, %rdi
movq -0x38(%rbp), %rsi
callq 0x1b9f0
movq -0x38(%rbp), %rdi
addq $0x20, %rdi
movq -0x40(%rbp), %rsi
callq 0x1b9f0
movq -0x28(%rbp), %rdi
callq 0x1f450
leaq 0x6d211(%rip), %rax     # 0x8bdb0
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xa0, %rsp
popq %rbp
retq