// File: /workspace/github_cpp_makefile_star2_O2/RuiDGPires[P]CrimLang/src/generator.cpp
// Function: gc_Tracker::declaration_cas(crl::Node*)
void _gc_Tracker::declaration_cas(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 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);
	size_t block_size = block->children.size();
	for (size_t i = 0; i < block_size; i++){
		ASSERT(block->get_child(i)->type == crl::Node::Type::LEAF, "ALL CHILDREN OF CAS DECLARATION MUST BE LEAFS");
		stream_funcs << get_token(block->get_child(i)).str << "\n";
	}

	this->stream_funcs << 
		"; End of function\n" <<
		name << "-end:\n" <<
		"MOV RS RF\n" <<
		"MVI R1 " << args_size + 2 << "\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 $0x228, %rsp            # imm = 0x228
movq %rsi, %r14
movq %rdi, %r15
movq (%rsi), %rax
movq %rsi, %rdi
xorl %esi, %esi
callq *0x18(%rax)
cmpl $0x10, 0x8(%rax)
jne 0x80c4
movq (%r14), %rax
pushq $0x1
popq %rsi
movq %r14, %rdi
callq *0x18(%rax)
cmpl $0x10, 0x8(%rax)
jne 0x8118
movq (%r14), %rax
movq %r14, %rdi
xorl %esi, %esi
callq *0x18(%rax)
leaq 0x58(%rax), %rsi
leaq -0x60(%rbp), %rbx
movq %rbx, %rdi
callq 0xb24a
leaq -0xf8(%rbp), %rax
movq %rax, -0x10(%rax)
movq (%rbx), %rcx
leaq -0x50(%rbp), %rdx
cmpq %rdx, %rcx
je 0x7ac7
movq %rcx, -0x108(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0xf8(%rbp)
jmp 0x7acd
movups (%rdx), %xmm0
movups %xmm0, (%rax)
leaq -0x60(%rbp), %rdi
movq 0x8(%rdi), %rax
movq %rax, -0x100(%rbp)
movq %rdx, (%rdi)
andq $0x0, 0x8(%rdi)
movb $0x0, 0x10(%rdi)
callq 0x135f8
movq (%r14), %rax
pushq $0x1
popq %rsi
movq %r14, %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 0x7b2f
movq %rcx, -0x90(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x80(%rbp)
jmp 0x7b35
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(%r15), %rdi
movq %rbx, %rsi
callq 0x3160
leaq -0x1a8(%rbp), %rdi
leaq -0x108(%rbp), %rsi
callq 0x32f0
leaq -0x1a8(%rbp), %rdi
callq 0x7909
movl %eax, %ebx
leaq -0x1a8(%rbp), %rdi
callq 0x3110
leaq 0x328(%r15), %rdi
leaq -0x90(%rbp), %rsi
movq %rdi, -0x30(%rbp)
callq 0x3220
leaq 0xd8f1(%rip), %rsi      # 0x154a4
movq %rax, %rdi
callq 0x3230
decl %ebx
movl %ebx, 0x5b0(%r15)
andl $0x0, 0x5ac(%r15)
leaq 0xd856(%rip), %rsi      # 0x15429
movq -0x30(%rbp), %rdi
callq 0x3230
leaq -0x90(%rbp), %rsi
movq %rax, %rdi
callq 0x3220
leaq 0xd8f1(%rip), %rsi      # 0x154e3
movq %rax, %rdi
callq 0x3230
leaq 0xd833(%rip), %rsi      # 0x15434
movq %rax, %rdi
callq 0x3230
leaq 0xd82f(%rip), %rsi      # 0x1543f
movq %rax, %rdi
callq 0x3230
leaq 0xd82b(%rip), %rsi      # 0x1544a
leaq -0x188(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x3be4
leaq 0x318(%r15), %rbx
leaq 0x530(%r15), %rdi
leaq -0x188(%rbp), %rsi
movq %rdi, -0x68(%rbp)
movq %rbx, %rdx
callq 0xac8a
leaq -0x188(%rbp), %rdi
callq 0x3110
leaq 0xd7ea(%rip), %rsi      # 0x1544d
leaq -0x168(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x3be4
movq %r15, -0xa0(%rbp)
leaq -0x168(%rbp), %rsi
movq -0x68(%rbp), %rdi
movq %rbx, -0x98(%rbp)
movq %rbx, %rdx
callq 0xac8a
leaq -0x168(%rbp), %rdi
callq 0x3110
xorl %ebx, %ebx
movq $0x0, -0x70(%rbp)
movq %r14, -0xa8(%rbp)
cmpl 0x50(%r14), %ebx
jae 0x7e5b
addl $0x2, %ebx
movq (%r14), %rax
movq %r14, %rdi
movl %ebx, %esi
callq *0x18(%rax)
movq %rax, %r13
movq (%rax), %rax
movq %r13, %rdi
xorl %esi, %esi
callq *0x18(%rax)
leaq -0x50(%rbp), %r12
addq $0x58, %rax
leaq -0x60(%rbp), %rdi
movq %rax, %rsi
callq 0xb24a
leaq -0xd8(%rbp), %rcx
movq %rcx, -0xe8(%rbp)
movq -0x60(%rbp), %rax
cmpq %r12, %rax
leaq -0x60(%rbp), %r14
je 0x7d1a
movq %rax, -0xe8(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0xd8(%rbp)
jmp 0x7d22
movups (%r12), %xmm0
movups %xmm0, (%rcx)
movq -0x58(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq %r12, -0x60(%rbp)
andq $0x0, -0x58(%rbp)
movb $0x0, -0x50(%rbp)
movq %r14, %rdi
callq 0x135f8
movq (%r13), %rax
movq %r13, %rdi
pushq $0x1
popq %rsi
callq *0x18(%rax)
addq $0x58, %rax
movq %r14, %rdi
movq %rax, %rsi
callq 0xb24a
leaq -0xb8(%rbp), %rcx
movq %rcx, -0xc8(%rbp)
movq -0x60(%rbp), %rax
cmpq %r12, %rax
je 0x7d89
movq %rax, -0xc8(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0xb8(%rbp)
jmp 0x7d91
movups (%r12), %xmm0
movups %xmm0, (%rcx)
leaq -0x60(%rbp), %rdi
movq -0x58(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq %r12, -0x60(%rbp)
andq $0x0, -0x58(%rbp)
movb $0x0, -0x50(%rbp)
callq 0x135f8
addq $0x30, %r13
movq %r13, %rdi
leaq 0xd690(%rip), %rsi      # 0x15450
callq 0x410a
movl %eax, %r13d
pushq $0x1
popq %r14
testb %al, %al
leaq -0x248(%rbp), %r15
jne 0x7e04
leaq -0x1e8(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x32f0
leaq -0x1e8(%rbp), %r12
movq %r12, %rdi
callq 0x7909
movl %eax, %r14d
movq %r12, %rdi
callq 0x3110
movq %r15, %rdi
leaq -0xc8(%rbp), %rsi
callq 0x32f0
movzbl %r13b, %ecx
movq -0x68(%rbp), %rdi
movq %r15, %rsi
movl %r14d, %edx
callq 0xacca
movl %r14d, %eax
addq %rax, -0x70(%rbp)
movq %r15, %rdi
callq 0x3110
leaq -0xc8(%rbp), %rdi
callq 0x3110
leaq -0xe8(%rbp), %rdi
callq 0x3110
decl %ebx
movq -0xa8(%rbp), %r14
jmp 0x7cb1
movq -0xa0(%rbp), %rax
movl 0x5b0(%rax), %ebx
leaq 0xd50e(%rip), %rsi      # 0x1537d
movq -0x30(%rbp), %rdi
callq 0x3230
movq %rax, %rdi
movq %rbx, %rsi
callq 0x3180
leaq 0xd659(%rip), %rsi      # 0x154e3
movq %rax, %rdi
callq 0x3230
leaq 0xd5bb(%rip), %rsi      # 0x15454
movq %rax, %rdi
callq 0x3230
movl 0x50(%r14), %esi
addl $0x2, %esi
movq (%r14), %rax
movq %r14, %rdi
callq *0x18(%rax)
movq %rax, %rbx
movq 0x18(%rax), %r13
subq 0x10(%rax), %r13
sarq $0x3, %r13
xorl %r14d, %r14d
leaq -0x60(%rbp), %r15
leaq 0xd615(%rip), %r12      # 0x154e3
cmpq %r14, %r13
je 0x7f28
movq (%rbx), %rax
movq %rbx, %rdi
movl %r14d, %esi
callq *0x18(%rax)
cmpl $0x10, 0x8(%rax)
jne 0x806d
movq (%rbx), %rax
movq %rbx, %rdi
movl %r14d, %esi
callq *0x18(%rax)
addq $0x58, %rax
movq %r15, %rdi
movq %rax, %rsi
callq 0xb24a
movq -0x30(%rbp), %rdi
movq %r15, %rsi
callq 0x3220
movq %rax, %rdi
movq %r12, %rsi
callq 0x3230
movq %r15, %rdi
callq 0x135f8
incq %r14
jmp 0x7ece
leaq 0xd55e(%rip), %rsi      # 0x1548d
movq -0x30(%rbp), %rdi
callq 0x3230
leaq -0x90(%rbp), %rsi
movq %rax, %rdi
callq 0x3220
leaq 0xd552(%rip), %rsi      # 0x154a0
movq %rax, %rdi
callq 0x3230
leaq 0xd54a(%rip), %rsi      # 0x154a7
movq %rax, %rdi
callq 0x3230
leaq 0xd411(%rip), %rsi      # 0x1537d
movq %rax, %rdi
callq 0x3230
movq -0x70(%rbp), %rsi
addq $0x2, %rsi
movq %rax, %rdi
callq 0x3180
leaq 0xd558(%rip), %rsi      # 0x154e3
movq %rax, %rdi
callq 0x3230
leaq 0xd518(%rip), %rsi      # 0x154b2
movq %rax, %rdi
callq 0x3230
leaq 0xd4a4(%rip), %rsi      # 0x1544d
leaq -0x148(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x3be4
movq -0x98(%rbp), %rbx
leaq -0x148(%rbp), %rsi
movq -0x68(%rbp), %rdi
movq %rbx, %rdx
callq 0xad9e
leaq -0x148(%rbp), %rdi
callq 0x3110
leaq 0xd4d7(%rip), %rsi      # 0x154bd
leaq -0x128(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x3be4
leaq -0x128(%rbp), %rsi
movq -0x68(%rbp), %rdi
movq %rbx, %rdx
callq 0xad9e
leaq -0x128(%rbp), %rdi
callq 0x3110
leaq 0xd4a4(%rip), %rsi      # 0x154c0
movq -0x30(%rbp), %rdi
callq 0x3230
leaq 0xd4a8(%rip), %rsi      # 0x154d4
movq %rax, %rdi
callq 0x3230
leaq 0xd4a4(%rip), %rsi      # 0x154df
movq %rax, %rdi
callq 0x3230
leaq -0x90(%rbp), %rdi
callq 0x3110
leaq -0x108(%rbp), %rdi
callq 0x3110
addq $0x228, %rsp            # imm = 0x228
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x50
popq %rdi
callq 0x3140
movq %rax, %r14
leaq 0xd3e0(%rip), %rsi      # 0x1545f
leaq -0x1c8(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x3be4
movb $0x1, %r15b
pushq $-0x1
popq %rdx
leaq -0x1c8(%rbp), %rcx
movq %r14, %rdi
movl %edx, %esi
callq 0x4e88
xorl %r15d, %r15d
leaq 0x15ce0(%rip), %rsi     # 0x1dd90
leaq -0x317f(%rip), %rdx     # 0x4f38
movq %r14, %rdi
callq 0x33f0
jmp 0x816a
pushq $0x50
popq %rdi
callq 0x3140
movq %rax, %r14
leaq 0xd2f0(%rip), %rsi      # 0x153c6
leaq -0x228(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x3be4
movb $0x1, %r15b
pushq $-0x1
popq %rdx
leaq -0x228(%rbp), %rcx
movq %r14, %rdi
movl %edx, %esi
callq 0x4e88
xorl %r15d, %r15d
leaq 0x15c89(%rip), %rsi     # 0x1dd90
leaq -0x31d6(%rip), %rdx     # 0x4f38
movq %r14, %rdi
callq 0x33f0
jmp 0x816a
pushq $0x50
popq %rdi
callq 0x3140
movq %rax, %r14
leaq 0xd2cd(%rip), %rsi      # 0x153f7
leaq -0x208(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x3be4
movb $0x1, %r15b
pushq $-0x1
popq %rdx
leaq -0x208(%rbp), %rcx
movq %r14, %rdi
movl %edx, %esi
callq 0x4e88
xorl %r15d, %r15d
leaq 0x15c35(%rip), %rsi     # 0x1dd90
leaq -0x322a(%rip), %rdx     # 0x4f38
movq %r14, %rdi
callq 0x33f0
movq %rax, %rbx
leaq -0x208(%rbp), %rdi
jmp 0x8182
jmp 0x8191
movq %rax, %rbx
leaq -0x228(%rbp), %rdi
callq 0x3110
testb %r15b, %r15b
jne 0x8194
jmp 0x82a9
movq %rax, %rbx
movq %r14, %rdi
callq 0x31b0
jmp 0x82a9
movq %rax, %rbx
leaq -0x128(%rbp), %rdi
jmp 0x8287
jmp 0x828e
movq %rax, %rbx
leaq -0x148(%rbp), %rdi
jmp 0x8287
jmp 0x828e
jmp 0x828e
movq %rax, %rbx
leaq -0x168(%rbp), %rdi
jmp 0x8287
jmp 0x828e
movq %rax, %rbx
leaq -0x188(%rbp), %rdi
jmp 0x8287
jmp 0x828e
movq %rax, %rbx
leaq -0x1a8(%rbp), %rdi
jmp 0x8287
jmp 0x828e
movq %rax, %rbx
jmp 0x829d
jmp 0x828e
jmp 0x828e
jmp 0x828e
movq %rax, %rbx
leaq -0x1c8(%rbp), %rdi
callq 0x3110
testb %r15b, %r15b
jne 0x8231
jmp 0x8291
movq %rax, %rbx
movq %r14, %rdi
callq 0x31b0
jmp 0x8291
movq %rax, %rbx
leaq -0x1e8(%rbp), %rdi
jmp 0x8253
jmp 0x828e
movq %rax, %rbx
leaq -0x248(%rbp), %rdi
callq 0x3110
jmp 0x825f
jmp 0x828e
movq %rax, %rbx
leaq -0xc8(%rbp), %rdi
callq 0x3110
jmp 0x8280
movq %rax, %rbx
leaq -0x60(%rbp), %rdi
callq 0x135f8
jmp 0x8291
jmp 0x828e
movq %rax, %rbx
leaq -0xe8(%rbp), %rdi
callq 0x3110
jmp 0x8291
movq %rax, %rbx
leaq -0x90(%rbp), %rdi
callq 0x3110
leaq -0x108(%rbp), %rdi
callq 0x3110
movq %rbx, %rdi
callq 0x3410
nop