// File: /workspace/github_c_makefile_star2_O0/lucvoo[P]sparse-dev/compile-i386.c
// Function: emit_switch_statement
static void emit_switch_statement(struct statement *stmt)
{
	struct storage *val = x86_expression(stmt->switch_expression);
	struct symbol *sym, *default_sym = NULL;
	struct storage *labelsym, *label;
	int switch_end = 0;

	emit_move(val, REG_EAX, stmt->switch_expression->ctype, "begin case");

	/*
	 * This is where a _real_ back-end would go through the
	 * cases to decide whether to use a lookup table or a
	 * series of comparisons etc
	 */
	FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) {
		struct statement *case_stmt = sym->stmt;
		struct expression *expr = case_stmt->case_expression;
		struct expression *to = case_stmt->case_to;

		/* default: */
		if (!expr)
			default_sym = sym;

		/* case NNN: */
		else {
			struct storage *case_val = new_val(expr->value);

			assert (expr->type == EXPR_VALUE);

			insn("cmpl", case_val, REG_EAX, NULL);

			if (!to) {
				labelsym = new_labelsym(sym);
				insn("je", labelsym, NULL, NULL);
			} else {
				int next_test;

				label = new_storage(STOR_LABEL);
				label->flags |= STOR_WANTS_FREE;
				label->label = next_test = new_label();

				/* FIXME: signed/unsigned */
				insn("jl", label, NULL, NULL);

				case_val = new_val(to->value);
				insn("cmpl", case_val, REG_EAX, NULL);

				/* TODO: implement and use refcounting... */
				label = new_storage(STOR_LABEL);
				label->flags |= STOR_WANTS_FREE;
				label->label = next_test;

				/* FIXME: signed/unsigned */
				insn("jg", label, NULL, NULL);

				labelsym = new_labelsym(sym);
				insn("jmp", labelsym, NULL, NULL);

				emit_label(next_test, NULL);
			}
		}
	} END_FOR_EACH_PTR(sym);

	if (default_sym) {
		labelsym = new_labelsym(default_sym);
		insn("jmp", labelsym, NULL, "default");
	} else {
		label = new_storage(STOR_LABEL);
		label->flags |= STOR_WANTS_FREE;
		label->label = switch_end = new_label();
		insn("jmp", label, NULL, "goto end of switch");
	}

	x86_statement(stmt->switch_statement);

	if (stmt->switch_break->used)
		emit_labelsym(stmt->switch_break, NULL);

	if (switch_end)
		emit_label(switch_end, NULL);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x62220
movq %rax, -0x10(%rbp)
movq $0x0, -0x20(%rbp)
movl $0x0, -0x34(%rbp)
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x10(%rax), %rdx
leaq 0x2faba(%rip), %rsi     # 0x92890
addq $0x330, %rsi            # imm = 0x330
leaq 0xfda0(%rip), %rcx      # 0x72b84
callq 0x63640
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x98(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0x62e18
jmp 0x6304d
jmp 0x62e1a
movl $0x0, -0x54(%rbp)
movl -0x54(%rbp), %eax
movq -0x48(%rbp), %rcx
movw (%rcx), %cx
shlw $0x8, %cx
sarw $0x8, %cx
movswl %cx, %ecx
cmpl %ecx, %eax
jge 0x63035
movq -0x48(%rbp), %rax
movslq -0x54(%rbp), %rcx
movq 0x18(%rax,%rcx,8), %rax
movq %rax, -0x18(%rbp)
movq -0x48(%rbp), %rax
movw (%rax), %ax
sarw $0x8, %ax
cwtl
cmpl $0x0, %eax
je 0x62e6c
cmpq $0x0, -0x18(%rbp)
jne 0x62e6c
jmp 0x63027
movq -0x18(%rbp), %rax
movq 0x90(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x60(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x70(%rbp)
cmpq $0x0, -0x68(%rbp)
jne 0x62ea7
movq -0x18(%rbp), %rax
movq %rax, -0x20(%rbp)
jmp 0x63025
movq -0x68(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x64300
movq %rax, -0x78(%rbp)
movq -0x68(%rbp), %rax
movl (%rax), %eax
andl $0xff, %eax
cmpl $0x1, %eax
jne 0x62eca
jmp 0x62ee9
leaq 0xf9ce(%rip), %rdi      # 0x7289f
leaq 0xf8bc(%rip), %rsi      # 0x72794
movl $0x6ca, %edx            # imm = 0x6CA
leaq 0xfcab(%rip), %rcx      # 0x72b8f
callq 0x11140
movq -0x78(%rbp), %rsi
leaq 0xfcca(%rip), %rdi      # 0x72bbe
leaq 0x2f995(%rip), %rdx     # 0x92890
addq $0x330, %rdx            # imm = 0x330
xorl %eax, %eax
movl %eax, %ecx
callq 0x63500
cmpq $0x0, -0x70(%rbp)
jne 0x62f3b
movq -0x18(%rbp), %rdi
callq 0x635f0
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rsi
leaq 0xfc99(%rip), %rdi      # 0x72bc3
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rdx
callq 0x63500
jmp 0x63023
movl $0x5, %edi
callq 0x63490
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rcx
orq $0x2, %rcx
movq %rcx, 0x8(%rax)
callq 0x62b30
movl %eax, %ecx
movl %ecx, -0x7c(%rbp)
movq -0x30(%rbp), %rax
movl %ecx, 0x20(%rax)
movq -0x30(%rbp), %rsi
leaq 0xfc51(%rip), %rdi      # 0x72bc6
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rdx
callq 0x63500
movq -0x70(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x64300
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rsi
leaq 0xfc21(%rip), %rdi      # 0x72bbe
leaq 0x2f8ec(%rip), %rdx     # 0x92890
addq $0x330, %rdx            # imm = 0x330
xorl %eax, %eax
movl %eax, %ecx
callq 0x63500
movl $0x5, %edi
callq 0x63490
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rcx
orq $0x2, %rcx
movq %rcx, 0x8(%rax)
movl -0x7c(%rbp), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x20(%rax)
movq -0x30(%rbp), %rsi
leaq 0xfbe2(%rip), %rdi      # 0x72bc9
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rdx
callq 0x63500
movq -0x18(%rbp), %rdi
callq 0x635f0
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rsi
leaq 0xa1ae(%rip), %rdi      # 0x6d1b9
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rdx
callq 0x63500
movl -0x7c(%rbp), %edi
xorl %eax, %eax
movl %eax, %esi
callq 0x63bd0
jmp 0x63025
jmp 0x63027
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x62e21
jmp 0x63037
movq -0x48(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x48(%rbp)
cmpq -0x40(%rbp), %rax
jne 0x62e1a
cmpq $0x0, -0x20(%rbp)
je 0x6307e
movq -0x20(%rbp), %rdi
callq 0x635f0
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rsi
leaq 0xa14d(%rip), %rdi      # 0x6d1b9
xorl %eax, %eax
movl %eax, %edx
leaq 0x8e8d(%rip), %rcx      # 0x6bf04
callq 0x63500
jmp 0x630c8
movl $0x5, %edi
callq 0x63490
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rcx
orq $0x2, %rcx
movq %rcx, 0x8(%rax)
callq 0x62b30
movl %eax, %ecx
movl %ecx, -0x34(%rbp)
movq -0x30(%rbp), %rax
movl %ecx, 0x20(%rax)
movq -0x30(%rbp), %rsi
leaq 0xa101(%rip), %rdi      # 0x6d1b9
xorl %eax, %eax
movl %eax, %edx
leaq 0xfb09(%rip), %rcx      # 0x72bcc
callq 0x63500
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x61d70
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movl (%rax), %eax
shrl $0x11, %eax
andl $0x1, %eax
cmpb $0x0, %al
je 0x630fa
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x64290
cmpl $0x0, -0x34(%rbp)
je 0x6310c
movl -0x34(%rbp), %edi
xorl %eax, %eax
movl %eax, %esi
callq 0x63bd0
addq $0x80, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)