// File: /workspace/github_c_makefile_star2_O1/been-jamming[P]MinimalCC/compile.c
// Function: compile_function
void compile_function(char **c, char *identifier_name, char *arguments, unsigned int identifier_length, unsigned int num_arguments, FILE *output_file){
	variable *var;
	variable *local_var;
	unsigned int current_argument = 0;

	num_vars = 0;
	variables_size = 0;
	return_type = EMPTY_TYPE;
	parse_type(&return_type, c, identifier_name, arguments, identifier_length, num_arguments);

	if(!identifier_name){
		snprintf(error_message, sizeof(error_message), "Expected identifier name");
		do_error(1);
	}
	skip_whitespace(c);
	if(peek_type(&return_type) != type_function){
		skip_whitespace(c);
		if(**c != ';'){
			snprintf(error_message, sizeof(error_message), "Expected ';'");
			do_error(1);
		}
		++*c;
		var = read_dictionary(global_variables, identifier_name, 0);
		if(var){
			snprintf(error_message, sizeof(error_message), "Duplicate definitions of non-function data");
			do_error(1);
		}
		var = malloc(sizeof(variable));
		var->var_type = return_type;
		var->varname = malloc(strlen(identifier_name) + 1);
		var->leave_as_address = 0;
		strcpy(var->varname, identifier_name);
		write_dictionary(&global_variables, var->varname, var, 0);
		fprintf(output_file, ".data\n.align 2\n%s:\n.space %d\n.text\n", identifier_name, align4(type_size(&return_type, 0)));
	} else {
		if(!*identifier_name){
			snprintf(error_message, sizeof(error_message), "Expected function name");
			do_error(1);
		}
		var = read_dictionary(global_variables, identifier_name, 0);
		if(!var){
			var = malloc(sizeof(variable));
			var->var_type = return_type;
			var->varname = malloc(strlen(identifier_name) + 1);
			var->leave_as_address = 1;
			strcpy(var->varname, identifier_name);
			write_dictionary(&global_variables, var->varname, var, 0);
		} else {
			if(!types_equal(&(var->var_type), &return_type)){
				snprintf(error_message, sizeof(error_message), "Incompatible function definitions");
				do_error(1);
			}
		}
		if(**c != '{'){
			if(**c != ';'){
				snprintf(error_message, sizeof(error_message), "Expected '{' or ';' instead of '%c'", **c);
				do_error(1);
			}
			++*c;
			return;
		}
		++*c;
		local_variables[0] = malloc(sizeof(dictionary));
		*local_variables[0] = create_dictionary(NULL);
		fprintf(output_file, "\n.globl %s\n%s:\n", identifier_name, identifier_name);
		pop_type(&return_type);
		while(peek_type(&return_type) != type_returns){
			if(current_argument >= num_arguments){
				snprintf(error_message, sizeof(error_message), "Too many arguments!");
				do_error(1);
			}
			if(read_dictionary(*local_variables[0], arguments, 0)){
				snprintf(error_message, sizeof(error_message), "Duplicate argument names");
				do_error(1);
			}
			local_var = malloc(sizeof(variable));
			local_var->var_type = get_argument_type(&return_type);
			local_var->varname = malloc(strlen(arguments) + 1);
			strcpy(local_var->varname, arguments);
			local_var->stack_pos = variables_size;
			write_dictionary(local_variables[0], local_var->varname, local_var, 0);
			variables_size += 4;
			arguments += identifier_length;
			current_argument++;
			num_vars++;
		}
		pop_type(&return_type);
		if(peek_type(&return_type) == type_function){
			snprintf(error_message, sizeof(error_message), "Function cannot return function");
			do_error(1);
		}
		num_args = num_vars;
		compile_block(c, 1, output_file);
		++*c;
		var->num_args = num_vars;
		fprintf(output_file, "lw $ra, %d($sp)\n", 4 + num_args*4);
		fprintf(output_file, "jr $ra\n");
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movq %r9, %r13
movl %r8d, %ebp
movl %ecx, %r12d
movq %rdx, %rcx
movq %rsi, %r14
movq %rdi, %rbx
xorl %eax, %eax
movl %eax, 0x769c(%rip)      # 0xd3d0
leaq 0x750d(%rip), %rdx      # 0xd248
movl %eax, (%rdx)
leaq 0x7a14(%rip), %rax      # 0xd758
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups 0x20(%rax), %xmm2
movups 0x30(%rax), %xmm3
movups %xmm0, 0x78ae(%rip)     # 0xd608
movups %xmm1, 0x78b7(%rip)     # 0xd618
movups %xmm2, 0x78c0(%rip)     # 0xd628
movups %xmm3, 0x78c9(%rip)     # 0xd638
leaq 0x7892(%rip), %rdi      # 0xd608
movq %rbx, %rsi
movq %r14, %rdx
movq %rcx, %r15
movl %r12d, %r8d
movl %ebp, %r9d
callq 0x7e04
testq %r14, %r14
je 0x6206
movq %rbx, %rdi
callq 0x799f
leaq 0x7866(%rip), %rdi      # 0xd608
callq 0x7a61
cmpl $0x5, %eax
jne 0x5e28
movq %r13, 0x58(%rsp)
cmpb $0x0, (%r14)
je 0x6220
leaq 0x74be(%rip), %rsi      # 0xd280
movl $0x9, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %r14, %rdi
xorl %esi, %esi
callq 0x734d
testq %rax, %rax
je 0x5f16
movq %rax, %r13
movq %rax, %rdi
addq $0x8, %rdi
leaq 0x7817(%rip), %rsi      # 0xd608
callq 0x7ab1
testb %al, %al
jne 0x5f95
movups 0x3ea6(%rip), %xmm0     # 0x9cab
movaps %xmm0, 0x76e4(%rip)     # 0xd4f0
movups 0x3e88(%rip), %xmm0     # 0x9c9b
movaps %xmm0, 0x76c6(%rip)     # 0xd4e0
movw $0x73, 0x76dd(%rip)     # 0xd500
jmp 0x62c8
movq %rbx, %rdi
callq 0x799f
movq (%rbx), %rax
cmpb $0x3b, (%rax)
jne 0x6244
incq (%rbx)
leaq 0x743a(%rip), %rsi      # 0xd280
movl $0x9, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %r14, %rdi
xorl %esi, %esi
callq 0x734d
testq %rax, %rax
jne 0x6268
movl $0x50, %edi
callq 0x1140
movq %rax, %rbx
movups 0x7790(%rip), %xmm0     # 0xd608
movups %xmm0, 0x8(%rax)
movups 0x7795(%rip), %xmm0     # 0xd618
movups %xmm0, 0x18(%rax)
movups 0x779a(%rip), %xmm0     # 0xd628
movups %xmm0, 0x28(%rax)
movups 0x779f(%rip), %xmm0     # 0xd638
movups %xmm0, 0x38(%rax)
leaq 0x7764(%rip), %r12      # 0xd608
movq %r14, %rdi
callq 0x1090
leaq 0x1(%rax), %rdi
callq 0x1140
movq %rax, %r15
movq %rax, (%rbx)
movb $0x0, 0x48(%rbx)
movq %rax, %rdi
movq %r14, %rsi
callq 0x1050
leaq 0x73af(%rip), %rdi      # 0xd280
movq %r15, %rsi
movq %rbx, %rdx
xorl %ecx, %ecx
callq 0x7405
movq %r12, %rdi
xorl %esi, %esi
callq 0x1984
movl %eax, %edi
callq 0x2b66
leaq 0x3d6a(%rip), %rsi      # 0x9c60
movq %r13, %rdi
movq %r14, %rdx
movl %eax, %ecx
xorl %eax, %eax
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1100
movl $0x50, %edi
callq 0x1140
movq %rax, %r13
movups 0x76de(%rip), %xmm0     # 0xd608
movups %xmm0, 0x8(%rax)
movups 0x76e3(%rip), %xmm0     # 0xd618
movups %xmm0, 0x18(%rax)
movups 0x76e8(%rip), %xmm0     # 0xd628
movups %xmm0, 0x28(%rax)
movups 0x76ed(%rip), %xmm0     # 0xd638
movups %xmm0, 0x38(%rax)
movq %r14, %rdi
callq 0x1090
leaq 0x1(%rax), %rdi
callq 0x1140
movl %r12d, 0x50(%rsp)
movq %rax, %r12
movq %rax, (%r13)
movb $0x1, 0x48(%r13)
movq %rax, %rdi
movq %r14, %rsi
callq 0x1050
leaq 0x72fd(%rip), %rdi      # 0xd280
movq %r12, %rsi
movl 0x50(%rsp), %r12d
movq %r13, %rdx
xorl %ecx, %ecx
callq 0x7405
movq (%rbx), %rax
movzbl (%rax), %ecx
cmpl $0x3b, %ecx
je 0x61ba
movq %r13, 0x68(%rsp)
cmpl $0x7b, %ecx
jne 0x628d
incq %rax
movq %rbx, 0x60(%rsp)
movq %rax, (%rbx)
movl $0x48, %edi
callq 0x1140
movq %rax, %r13
leaq 0x72ff(%rip), %rax      # 0xd2d0
movq %r13, (%rax)
leaq 0x70(%rsp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x728c
movl $0x9, %ecx
movq %r13, %rdi
movq %rbx, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x3ce9(%rip), %rsi      # 0x9ce1
movq 0x58(%rsp), %rdi
movq %r14, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x1100
leaq 0x75f7(%rip), %rbx      # 0xd608
movq %rbx, %rdi
callq 0x7a79
movq %rbx, %rdi
callq 0x7a61
cmpl $0x6, %eax
je 0x6129
movq %r15, %r14
movl %r12d, %eax
movq %rax, 0x50(%rsp)
incl %ebp
decl %ebp
je 0x61cf
movl %ebp, %r15d
leaq 0x7287(%rip), %rbx      # 0xd2d0
movq (%rbx), %rsi
movl $0x9, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %r14, %rdi
xorl %esi, %esi
callq 0x734d
testq %rax, %rax
jne 0x61ec
movl $0x50, %edi
callq 0x1140
movq %rax, %r13
leaq 0x70(%rsp), %rdi
leaq 0x7585(%rip), %rsi      # 0xd608
callq 0x7bd9
movups 0x70(%rsp), %xmm0
movups 0x80(%rsp), %xmm1
movups 0x90(%rsp), %xmm2
movups 0xa0(%rsp), %xmm3
movups %xmm3, 0x38(%r13)
movups %xmm2, 0x28(%r13)
movups %xmm1, 0x18(%r13)
movups %xmm0, 0x8(%r13)
movq %r14, %rdi
callq 0x1090
leaq 0x1(%rax), %rdi
callq 0x1140
movq %r14, %rbp
movq %rax, %r14
movq %rax, (%r13)
movq %rax, %rdi
movq %rbp, %rsi
callq 0x1050
leaq 0x7162(%rip), %r12      # 0xd248
movl (%r12), %eax
movl %eax, 0x48(%r13)
movq (%rbx), %rdi
movq %r14, %rsi
movq %rbp, %r14
movq %r13, %rdx
xorl %ecx, %ecx
callq 0x7405
addl $0x4, (%r12)
addq 0x50(%rsp), %r14
incl 0x72bf(%rip)            # 0xd3d0
leaq 0x74f0(%rip), %rdi      # 0xd608
callq 0x7a61
cmpl $0x6, %eax
movl %r15d, %ebp
jne 0x6037
leaq 0x74d8(%rip), %rbx      # 0xd608
movq %rbx, %rdi
callq 0x7a79
movq %rbx, %rdi
callq 0x7a61
cmpl $0x5, %eax
movq 0x68(%rsp), %r15
je 0x62ac
movl 0x727c(%rip), %eax      # 0xd3d0
movl %eax, 0x727a(%rip)      # 0xd3d4
movq 0x60(%rsp), %r14
movq %r14, %rdi
movl $0x1, %esi
movq 0x58(%rsp), %rbx
movq %rbx, %rdx
callq 0x62d2
incq (%r14)
movl 0x7253(%rip), %eax      # 0xd3d0
movl %eax, 0x4c(%r15)
movl 0x724d(%rip), %eax      # 0xd3d4
leal 0x4(,%rax,4), %edx
leaq 0x3ba9(%rip), %rsi      # 0x9d3e
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1100
leaq 0x3ba9(%rip), %rdi      # 0x9d4f
movl $0x7, %esi
movl $0x1, %edx
movq %rbx, %rcx
callq 0x1190
jmp 0x61bd
incq (%rbx)
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movups 0x3b1b(%rip), %xmm0     # 0x9cf1
movaps %xmm0, 0x7303(%rip)     # 0xd4e0
movl $0x217374, 0x7309(%rip) # imm = 0x217374
jmp 0x62c8
movups 0x3b1b(%rip), %xmm0     # 0x9d0e
movups %xmm0, 0x72ef(%rip)     # 0xd4e9
movups 0x3b04(%rip), %xmm0     # 0x9d05
jmp 0x62c1
movups 0x3a18(%rip), %xmm0     # 0x9c25
movups %xmm0, 0x72d5(%rip)     # 0xd4e9
movups 0x3a01(%rip), %xmm0     # 0x9c1c
jmp 0x62c1
movups 0x3a5d(%rip), %xmm0     # 0x9c84
movaps %xmm0, 0x72b2(%rip)     # 0xd4e0
movabsq $0x656d616e206e6f, %rax # imm = 0x656D616E206E6F
movq %rax, 0x72b0(%rip)      # 0xd4ef
jmp 0x62c8
movabsq $0x273b2720646574, %rax # imm = 0x273B2720646574
movq %rax, 0x7290(%rip)      # 0xd4e5
movabsq $0x6465746365707845, %rax # imm = 0x6465746365707845
movq %rax, 0x727a(%rip)      # 0xd4e0
jmp 0x62c8
movups 0x39e1(%rip), %xmm0     # 0x9c50
movups %xmm0, 0x7285(%rip)     # 0xd4fb
movups 0x39c8(%rip), %xmm0     # 0x9c45
movaps %xmm0, 0x726c(%rip)     # 0xd4f0
movups 0x39aa(%rip), %xmm0     # 0x9c35
jmp 0x62c1
movsbl %cl, %ecx
leaq 0x7249(%rip), %rdi      # 0xd4e0
leaq 0x3a1f(%rip), %rdx      # 0x9cbd
movl $0x100, %esi            # imm = 0x100
xorl %eax, %eax
callq 0x10c0
jmp 0x62c8
movups 0x3a7b(%rip), %xmm0     # 0x9d2e
movaps %xmm0, 0x7236(%rip)     # 0xd4f0
movups 0x3a5d(%rip), %xmm0     # 0x9d1e
movaps %xmm0, 0x7218(%rip)     # 0xd4e0
movl $0x1, %edi
callq 0x5ae0