// File: /workspace/github_c_makefile_star2_O2/Mithreindeir[P]ewcc/src/tac.c
// Function: generate_from_node
struct ir_operand *generate_from_node(struct node *n, struct generator *context, int result)
{
	if (!n) return NULL;
	struct ir_operand *r = NULL;
	struct node *last = context->parent;
	context->parent = n;
	switch (n->type) {
	case node_block: 	block_emit(context, BLOCK(n)); break;
	case node_cond: 	cond_emit(context, COND(n)); break;
	case node_decl: 	decl_emit(context, DECL(n)); break;
	case node_loop:		loop_emit(context, LOOP(n)); break;
	case node_cast:		r = generate_from_node(n->child, context, result); break;
	case node_call: 	r = call_emit(context, CALL(n), result); break;
	case node_ident:    	r = ident_emit(context, IDENT(n), result); break;
	case node_cnum:		r = from_cnum(CNUM(n)); break;
	case node_unop:
		r = unop_emit(context, UNOP(n), result);
		/*The final value gets the type of the unary expression*/
		if (r &&& TYPE(n)) r->size = resolve_size(TYPE(n));
		break;
	case node_binop:
		r = binop_emit(context, BINOP(n), result);
		/*The final value gets the type of the binary expression*/
		if (r &&& TYPE(n)) r->size = resolve_size(TYPE(n));
		break;
	case node_unit:
		for (int i = 0; i < UNIT(n)->num_decls; i++)
			generate_from_node(UNIT(n)->edecls[i], context, IGNORE);
		break;
	case node_func:
		generate_from_node(FUNC(n)->body, context, IGNORE);
		int end = REQ_LABEL(context);
		emit_label(context, end);
		backpatch(FLIST_REF(FUNC(n)->body), end);
		struct ir_stmt *s = ir_stmt_init();
		s->type = stmt_ret;
		emit(context, s);
		break;
	case node_break:
		FLIST(n) = make_list(emit_jump(context, -1, UNCONDITIONAL));
		break;
	case node_continue:
		TLIST(n) = make_list(emit_jump(context, -1, UNCONDITIONAL));
		break;
	case node_return:
		s = ir_stmt_init();
		s->type = stmt_retval;
		s->arg1 = generate_from_node(RET(n), context, VALUE);
		emit(context, s);
		FLIST(n) = make_list(emit_jump(context, -1, UNCONDITIONAL));
		break;
	case node_empty: break;
	default:
		printf("Unknown AST Node %d\n", n->type);
		exit(-1);
		break;
	}
	context->parent = last;
	return r;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
testq %rdi, %rdi
je 0x3fea
movq %rsi, %rbx
movq %rdi, %r14
movq 0x20(%rsi), %r12
movq %rdi, 0x20(%rsi)
movl (%rdi), %esi
cmpq $0xf, %rsi
ja 0x41c0
leaq 0x437c(%rip), %rax      # 0x834c
movslq (%rax,%rsi,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq 0x8(%r14), %rdi
movq %rbx, %rsi
callq 0x3f9f
jmp 0x40de
xorl %r15d, %r15d
jmp 0x41ae
pushq $-0x1
popq %rsi
pushq $0x2
popq %rdx
movq %rbx, %rdi
callq 0x4bb4
movq %rax, %rdi
callq 0x4b81
movq 0x10(%r14), %rcx
movq %rax, 0x8(%rcx)
jmp 0x41a7
movq 0x8(%r14), %rsi
movq %rbx, %rdi
callq 0x4464
jmp 0x41a7
movq 0x8(%r14), %rax
movq (%rax), %rdi
callq 0x4733
jmp 0x40de
movq 0x8(%r14), %rsi
movq %rbx, %rdi
callq 0x43cc
jmp 0x41a7
movq 0x8(%r14), %rsi
movq %rbx, %rdi
callq 0x41d6
jmp 0x41a7
xorl %r15d, %r15d
pushq $0x3
popq %rbp
xorl %r13d, %r13d
movq 0x8(%r14), %rax
movslq 0x8(%rax), %rcx
cmpq %rcx, %r13
jge 0x41aa
movq (%rax), %rax
movq (%rax,%r13,8), %rdi
movq %rbx, %rsi
movl %ebp, %edx
callq 0x3f9f
incq %r13
jmp 0x4062
callq 0x4d88
movq %rax, %r15
movl $0x8, (%rax)
movq 0x8(%r14), %rdi
pushq $0x2
popq %rbp
movq %rbx, %rsi
movl %ebp, %edx
callq 0x3f9f
movq %rax, 0x10(%r15)
movq %rbx, %rdi
movq %r15, %rsi
callq 0x4b43
pushq $-0x1
popq %rsi
movq %rbx, %rdi
movl %ebp, %edx
jmp 0x40fd
movq 0x8(%r14), %rax
movq (%rax), %rsi
movq %rbx, %rdi
callq 0x4696
jmp 0x40de
movq 0x8(%r14), %rsi
movq %rbx, %rdi
callq 0x45a4
movq %rax, %r15
jmp 0x41aa
movq 0x8(%r14), %rsi
movq %rbx, %rdi
callq 0x4752
jmp 0x4123
pushq $-0x1
popq %rsi
pushq $0x2
popq %rdx
movq %rbx, %rdi
callq 0x4bb4
movq %rax, %rdi
callq 0x4b81
movq 0x10(%r14), %rcx
movq %rax, 0x10(%rcx)
jmp 0x41a7
movq 0x8(%r14), %rsi
movq %rbx, %rdi
callq 0x48f7
testq %rax, %rax
je 0x41a7
movq %rax, %r15
movq 0x10(%r14), %rax
testq %rax, %rax
je 0x41aa
movq (%rax), %rdi
callq 0x7583
movl %eax, 0x4(%r15)
jmp 0x41aa
movq 0x8(%r14), %rsi
movq %rbx, %rdi
callq 0x426e
jmp 0x41a7
movq 0x8(%r14), %rax
movq 0x10(%rax), %rdi
pushq $0x3
popq %rdx
movq %rbx, %rsi
callq 0x3f9f
movl 0x4(%rbx), %r15d
leal 0x1(%r15), %eax
movl %eax, 0x4(%rbx)
movq %rbx, %rdi
movl %r15d, %esi
callq 0x4ada
movq 0x8(%r14), %rax
movq 0x10(%rax), %rax
movq 0x10(%rax), %rdi
addq $0x10, %rdi
movl %r15d, %esi
callq 0x4b09
callq 0x4d88
movl $0x9, (%rax)
movq %rbx, %rdi
movq %rax, %rsi
callq 0x4b43
xorl %r15d, %r15d
movq %r12, 0x20(%rbx)
movq %r15, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x4229(%rip), %rdi      # 0x83f0
xorl %eax, %eax
callq 0x2080
pushq $-0x1
popq %rdi
callq 0x2110