// File: /workspace/github_cpp_makefile_star2_O2/RuiDGPires[P]CrimLang/src/generator.cpp
// Function: gc_Tracker::declaration_func(crl::Node*)
void _gc_Tracker::declaration_func(crl::Node *node){
	ASSERT(node->get_child(0)->type == crl::Node::Type::LEAF, "Func declaration must have a type as first token");
	ASSERT(node->get_child(1)->type == crl::Node::Type::LEAF, "Func declaration must have a name as second token");
	std::string type = get_token(node->get_child(0)).str;
	std::string name = get_token(node->get_child(1)).str;
	this->current_func_name = name;
	u32 size = size_of(type);

	stream_funcs << name << ":\n"; 
	
	// RESULT SPACE ALLOCATION MUST BE DONE BY CALLER
	
	symb_tracker.frame_offset = size - 1;
	symb_tracker.sp = 0;

	this->stream_funcs << 
		";Function " << name << "\n" <<
		"MOV R7 RF\n" << // TMP STORE RF
		"MOV RF RS\n";

	symb_tracker.push("R7", stream_funcs);
	symb_tracker.push("RE", stream_funcs);


	// Arguents will be stored on the stack like this:
	// foo(a, b, c) -> [a b c]

	// TREAT ARGMENTS
	size_t s = symb_tracker.check();
	size_t args_size = 0;
	for(u32 i = 0; i < node->argc; i++){
		crl::Node *arg = node->get_child(2 + i);
		std::string type = get_token(arg->get_child(0)).str;
		std::string name = get_token(arg->get_child(1)).str;

		bool is_mut = arg->annotation == "mut";
		u32 arg_size = is_mut? 1: size_of(type);
		args_size += arg_size;
		
		symb_tracker.arg_create(name, arg_size, is_mut);
	}

	u32 rollback = symb_tracker.frame_offset;	
	this->stream_funcs <<
		"MVI R1 " << rollback << "\n" <<
		"ADD RF R1\n"; // Rollback frame

	crl::Node *block = node->get_child(2+node->argc);
	ASSERT(block->type == crl::Node::Type::BLOCK, "Funcs must have a block");
	

	this->block(block);
	symb_tracker.clean(s);

	this->stream_funcs << 
		"; End of function\n" <<
		name << "-end:\n" <<
		"MOV RS RF\n" <<
		"MVI R1 " << args_size + 1 + size << "\n" <<
		"SUB RS R1\n";
		
	symb_tracker.pop("RE", stream_funcs);
	symb_tracker.pop("RF", stream_funcs);

	this->stream_funcs <<
		"MVI R2 2\n"
		"SUB R1 R2\n" <<
		"ADD RS R1\n" <<
		"RET\n\n";
		// The rest is the result (on stack)
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x238, %rsp            # imm = 0x238
movq %rsi, %r15
movq %rdi, %r14
movq (%rsi), %rax
movq %rsi, %rdi
xorl %esi, %esi
callq *0x18(%rax)
cmpl $0x10, 0x8(%rax)
jne 0x88bc
movq (%r15), %rax
pushq $0x1
popq %rsi
movq %r15, %rdi
callq *0x18(%rax)
cmpl $0x10, 0x8(%rax)
jne 0x8913
movq (%r15), %rax
movq %r15, %rdi
xorl %esi, %esi
callq *0x18(%rax)
leaq 0x58(%rax), %rsi
leaq -0x60(%rbp), %rbx
movq %rbx, %rdi
callq 0xb24a
leaq -0x108(%rbp), %rax
movq %rax, -0x10(%rax)
movq (%rbx), %rcx
leaq -0x50(%rbp), %rdx
cmpq %rdx, %rcx
je 0x833d
movq %rcx, -0x118(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x108(%rbp)
jmp 0x8343
movups (%rdx), %xmm0
movups %xmm0, (%rax)
leaq -0x60(%rbp), %rdi
movq 0x8(%rdi), %rax
movq %rax, -0x110(%rbp)
movq %rdx, (%rdi)
andq $0x0, 0x8(%rdi)
movb $0x0, 0x10(%rdi)
callq 0x135f8
movq (%r15), %rax
pushq $0x1
popq %rsi
movq %r15, %rdi
callq *0x18(%rax)
addq $0x58, %rax
leaq -0x60(%rbp), %rdi
movq %rax, %rsi
callq 0xb24a
leaq -0x80(%rbp), %rax
movq %rax, -0x10(%rax)
movq -0x60(%rbp), %rcx
leaq -0x50(%rbp), %rdx
cmpq %rdx, %rcx
je 0x83a5
movq %rcx, -0x90(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x80(%rbp)
jmp 0x83ab
movups (%rdx), %xmm0
movups %xmm0, (%rax)
leaq -0x60(%rbp), %rdi
movq 0x8(%rdi), %rax
leaq -0x90(%rbp), %rbx
movq %rax, 0x8(%rbx)
movq %rdx, (%rdi)
andq $0x0, 0x8(%rdi)
movb $0x0, 0x10(%rdi)
callq 0x135f8
leaq 0x4a0(%r14), %rdi
movq %rbx, %rsi
callq 0x3160
leaq -0x1b8(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0x32f0
leaq -0x1b8(%rbp), %rdi
callq 0x7909
movl %eax, %r12d
leaq -0x1b8(%rbp), %rdi
callq 0x3110
leaq 0x328(%r14), %rbx
leaq -0x90(%rbp), %rsi
movq %rbx, %rdi
callq 0x3220
leaq 0xd07b(%rip), %rsi      # 0x154a4
movq %rax, %rdi
callq 0x3230
leal -0x1(%r12), %eax
movl %eax, 0x5b0(%r14)
andl $0x0, 0x5ac(%r14)
leaq 0xcfdd(%rip), %rsi      # 0x15429
movq %rbx, %rdi
callq 0x3230
leaq -0x90(%rbp), %rsi
movq %rax, %rdi
callq 0x3220
leaq 0xd079(%rip), %rsi      # 0x154e3
movq %rax, %rdi
callq 0x3230
leaq 0xcfbb(%rip), %rsi      # 0x15434
movq %rax, %rdi
callq 0x3230
leaq 0xcfb7(%rip), %rsi      # 0x1543f
movq %rax, %rdi
callq 0x3230
leaq 0xcfb3(%rip), %rsi      # 0x1544a
leaq -0x198(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x3be4
leaq 0x318(%r14), %r13
leaq 0x530(%r14), %rdi
leaq -0x198(%rbp), %rsi
movq %rdi, -0x30(%rbp)
movq %r13, %rdx
callq 0xac8a
leaq -0x198(%rbp), %rdi
callq 0x3110
leaq 0xcf72(%rip), %rsi      # 0x1544d
leaq -0x178(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x3be4
movq %r12, -0xa8(%rbp)
movq %rbx, -0xb8(%rbp)
leaq -0x178(%rbp), %rsi
movq -0x30(%rbp), %rdi
movq %r13, -0xa0(%rbp)
movq %r13, %rdx
callq 0xac8a
leaq -0x178(%rbp), %rdi
callq 0x3110
movq %r14, -0xb0(%rbp)
movq 0x5a0(%r14), %rax
movq %rax, -0x98(%rbp)
xorl %r13d, %r13d
movq $0x0, -0x68(%rbp)
movq %r15, -0x70(%rbp)
cmpl 0x50(%r15), %r13d
jae 0x86eb
addl $0x2, %r13d
movq (%r15), %rax
movq %r15, %rdi
movl %r13d, %esi
callq *0x18(%rax)
movq %rax, %r12
movq (%rax), %rax
movq %r12, %rdi
xorl %esi, %esi
callq *0x18(%rax)
leaq -0x50(%rbp), %r14
addq $0x58, %rax
leaq -0x60(%rbp), %rdi
movq %rax, %rsi
callq 0xb24a
leaq -0xe8(%rbp), %rcx
movq %rcx, -0xf8(%rbp)
movq -0x60(%rbp), %rax
cmpq %r14, %rax
leaq -0x60(%rbp), %r15
je 0x85ae
movq %rax, -0xf8(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0xe8(%rbp)
jmp 0x85b5
movups (%r14), %xmm0
movups %xmm0, (%rcx)
movq -0x58(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq %r14, -0x60(%rbp)
andq $0x0, -0x58(%rbp)
movb $0x0, -0x50(%rbp)
movq %r15, %rdi
callq 0x135f8
movq (%r12), %rax
movq %r12, %rdi
pushq $0x1
popq %rsi
callq *0x18(%rax)
addq $0x58, %rax
movq %r15, %rdi
movq %rax, %rsi
callq 0xb24a
leaq -0xc8(%rbp), %rcx
movq %rcx, -0xd8(%rbp)
movq -0x60(%rbp), %rax
cmpq %r14, %rax
je 0x861c
movq %rax, -0xd8(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0xc8(%rbp)
jmp 0x8623
movups (%r14), %xmm0
movups %xmm0, (%rcx)
leaq -0x60(%rbp), %rdi
movq -0x58(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq %r14, -0x60(%rbp)
andq $0x0, -0x58(%rbp)
movb $0x0, -0x50(%rbp)
callq 0x135f8
addq $0x30, %r12
movq %r12, %rdi
leaq 0xcdfe(%rip), %rsi      # 0x15450
callq 0x410a
movl %eax, %r12d
pushq $0x1
popq %r15
testb %al, %al
leaq -0x258(%rbp), %rbx
jne 0x8696
leaq -0x1f8(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
callq 0x32f0
leaq -0x1f8(%rbp), %r14
movq %r14, %rdi
callq 0x7909
movl %eax, %r15d
movq %r14, %rdi
callq 0x3110
movq %rbx, %rdi
leaq -0xd8(%rbp), %rsi
callq 0x32f0
movzbl %r12b, %ecx
movq -0x30(%rbp), %rdi
movq %rbx, %rsi
movl %r15d, %edx
callq 0xacca
movl %r15d, %eax
addq %rax, -0x68(%rbp)
movq %rbx, %rdi
callq 0x3110
leaq -0xd8(%rbp), %rdi
callq 0x3110
leaq -0xf8(%rbp), %rdi
callq 0x3110
decl %r13d
movq -0x70(%rbp), %r15
jmp 0x8543
movq -0xb0(%rbp), %r15
movl 0x5b0(%r15), %ebx
leaq 0xcc7d(%rip), %rsi      # 0x1537d
movq -0xb8(%rbp), %r14
movq %r14, %rdi
callq 0x3230
movq %rax, %rdi
movq %rbx, %rsi
callq 0x3180
leaq 0xcdc2(%rip), %rsi      # 0x154e3
movq %rax, %rdi
callq 0x3230
leaq 0xcd24(%rip), %rsi      # 0x15454
movq %rax, %rdi
callq 0x3230
movq -0x70(%rbp), %rdi
movl 0x50(%rdi), %esi
addl $0x2, %esi
movq (%rdi), %rax
callq *0x18(%rax)
movq -0xa8(%rbp), %rbx
movq -0xa0(%rbp), %r12
cmpl $0x5, 0x8(%rax)
jne 0x8967
movq %r15, %rdi
movq %rax, %rsi
callq 0x8ad4
movq -0x30(%rbp), %rdi
movq -0x98(%rbp), %rsi
callq 0xadde
leaq 0xcd0b(%rip), %rsi      # 0x1548d
movq %r14, %rdi
callq 0x3230
leaq -0x90(%rbp), %rsi
movq %rax, %rdi
callq 0x3220
leaq 0xcd00(%rip), %rsi      # 0x154a0
movq %rax, %rdi
callq 0x3230
leaq 0xccf8(%rip), %rsi      # 0x154a7
movq %rax, %rdi
callq 0x3230
leaq 0xcbbf(%rip), %rsi      # 0x1537d
movq %rax, %rdi
callq 0x3230
movl %ebx, %ecx
movq -0x68(%rbp), %rdx
leaq (%rcx,%rdx), %rsi
incq %rsi
movq %rax, %rdi
callq 0x3180
leaq 0xcd01(%rip), %rsi      # 0x154e3
movq %rax, %rdi
callq 0x3230
leaq 0xccc1(%rip), %rsi      # 0x154b2
movq %rax, %rdi
callq 0x3230
leaq 0xcc4d(%rip), %rsi      # 0x1544d
leaq -0x158(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x3be4
leaq -0x158(%rbp), %rsi
movq -0x30(%rbp), %rdi
movq %r12, %rdx
callq 0xad9e
leaq -0x158(%rbp), %rdi
callq 0x3110
leaq 0xcc87(%rip), %rsi      # 0x154bd
leaq -0x138(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x3be4
leaq -0x138(%rbp), %rsi
movq -0x30(%rbp), %rdi
movq %r12, %rdx
callq 0xad9e
leaq -0x138(%rbp), %rdi
callq 0x3110
leaq 0xcc54(%rip), %rsi      # 0x154c0
movq %r14, %rdi
callq 0x3230
leaq 0xcc59(%rip), %rsi      # 0x154d4
movq %rax, %rdi
callq 0x3230
leaq 0xcc55(%rip), %rsi      # 0x154df
movq %rax, %rdi
callq 0x3230
leaq -0x90(%rbp), %rdi
callq 0x3110
leaq -0x118(%rbp), %rdi
callq 0x3110
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x50
popq %rdi
callq 0x3140
movq %rax, %r14
leaq 0xcaf8(%rip), %rsi      # 0x153c6
leaq -0x238(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x3be4
movb $0x1, %r15b
pushq $-0x1
popq %rdx
leaq -0x238(%rbp), %rcx
movq %r14, %rdi
movl %edx, %esi
callq 0x4e88
xorl %r15d, %r15d
leaq 0x15491(%rip), %rsi     # 0x1dd90
leaq -0x39ce(%rip), %rdx     # 0x4f38
movq %r14, %rdi
callq 0x33f0
jmp 0x89b9
pushq $0x50
popq %rdi
callq 0x3140
movq %rax, %r14
leaq 0xcad2(%rip), %rsi      # 0x153f7
leaq -0x218(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x3be4
movb $0x1, %r15b
pushq $-0x1
popq %rdx
leaq -0x218(%rbp), %rcx
movq %r14, %rdi
movl %edx, %esi
callq 0x4e88
xorl %r15d, %r15d
leaq 0x1543a(%rip), %rsi     # 0x1dd90
leaq -0x3a25(%rip), %rdx     # 0x4f38
movq %r14, %rdi
callq 0x33f0
jmp 0x89b9
pushq $0x50
popq %rdi
callq 0x3140
movq %rax, %r14
leaq 0xcb6c(%rip), %rsi      # 0x154e5
leaq -0x1d8(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x3be4
movb $0x1, %r15b
pushq $-0x1
popq %rdx
leaq -0x1d8(%rbp), %rcx
movq %r14, %rdi
movl %edx, %esi
callq 0x4e88
xorl %r15d, %r15d
leaq 0x153e6(%rip), %rsi     # 0x1dd90
leaq -0x3a79(%rip), %rdx     # 0x4f38
movq %r14, %rdi
callq 0x33f0
movq %rax, %rbx
leaq -0x1d8(%rbp), %rdi
callq 0x3110
testb %r15b, %r15b
jne 0x89d5
jmp 0x8ab4
movq %rax, %rbx
movq %r14, %rdi
callq 0x31b0
jmp 0x8ab4
movq %rax, %rbx
leaq -0x218(%rbp), %rdi
jmp 0x89fa
jmp 0x8a09
movq %rax, %rbx
leaq -0x238(%rbp), %rdi
callq 0x3110
testb %r15b, %r15b
jne 0x8a0c
jmp 0x8acc
movq %rax, %rbx
movq %r14, %rdi
callq 0x31b0
jmp 0x8acc
movq %rax, %rbx
leaq -0x138(%rbp), %rdi
jmp 0x8aaa
jmp 0x8ab1
movq %rax, %rbx
leaq -0x158(%rbp), %rdi
jmp 0x8aaa
jmp 0x8ab1
movq %rax, %rbx
leaq -0x178(%rbp), %rdi
jmp 0x8aaa
jmp 0x8ab1
movq %rax, %rbx
leaq -0x198(%rbp), %rdi
jmp 0x8aaa
jmp 0x8ab1
movq %rax, %rbx
leaq -0x1b8(%rbp), %rdi
jmp 0x8aaa
jmp 0x8ab1
movq %rax, %rbx
jmp 0x8ac0
jmp 0x8ab1
jmp 0x8ab1
jmp 0x8ab1
movq %rax, %rbx
leaq -0x1f8(%rbp), %rdi
jmp 0x8a86
movq %rax, %rbx
leaq -0x258(%rbp), %rdi
callq 0x3110
jmp 0x8a92
jmp 0x8ab1
movq %rax, %rbx
leaq -0xd8(%rbp), %rdi
callq 0x3110
jmp 0x8aa3
movq %rax, %rbx
leaq -0xf8(%rbp), %rdi
callq 0x3110
jmp 0x8ab4
movq %rax, %rbx
leaq -0x90(%rbp), %rdi
callq 0x3110
leaq -0x118(%rbp), %rdi
callq 0x3110
movq %rbx, %rdi
callq 0x3410