// File: /workspace/github_c_makefile_star2_O3/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, 0x766a(%rip)      # 0xd3d0
leaq 0x74db(%rip), %rdx      # 0xd248
movl %eax, (%rdx)
leaq 0x79e2(%rip), %rax      # 0xd758
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups 0x20(%rax), %xmm2
movups 0x30(%rax), %xmm3
movups %xmm0, 0x787c(%rip)     # 0xd608
movups %xmm1, 0x7885(%rip)     # 0xd618
movups %xmm2, 0x788e(%rip)     # 0xd628
movups %xmm3, 0x7897(%rip)     # 0xd638
leaq 0x7860(%rip), %rdi      # 0xd608
movq %rbx, %rsi
movq %r14, %rdx
movq %rcx, %r15
movl %r12d, %r8d
movl %ebp, %r9d
callq 0x7e08
testq %r14, %r14
je 0x623e
movq %rbx, %rdi
callq 0x79e2
leaq 0x7834(%rip), %rdi      # 0xd608
callq 0x7a9c
cmpl $0x5, %eax
jne 0x5e5a
movq %r13, 0x58(%rsp)
cmpb $0x0, (%r14)
je 0x6258
leaq 0x748c(%rip), %rsi      # 0xd280
movl $0x9, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %r14, %rdi
xorl %esi, %esi
callq 0x7389
testq %rax, %rax
je 0x5f4b
movq %rax, %r13
movq %rax, %rdi
addq $0x8, %rdi
leaq 0x77e5(%rip), %rsi      # 0xd608
callq 0x7aec
testb %al, %al
jne 0x5fca
movups 0x3e74(%rip), %xmm0     # 0x9cab
movaps %xmm0, 0x76b2(%rip)     # 0xd4f0
movups 0x3e56(%rip), %xmm0     # 0x9c9b
movaps %xmm0, 0x7694(%rip)     # 0xd4e0
movw $0x73, 0x76ab(%rip)     # 0xd500
jmp 0x6300
movq %rbx, %rdi
callq 0x79e2
movq (%rbx), %rax
cmpb $0x3b, (%rax)
jne 0x627c
incq %rax
movq %rax, (%rbx)
leaq 0x7405(%rip), %rsi      # 0xd280
movl $0x9, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %r14, %rdi
xorl %esi, %esi
callq 0x7389
testq %rax, %rax
jne 0x62a0
movl $0x50, %edi
callq 0x1140
movq %rax, %rbx
movups 0x775b(%rip), %xmm0     # 0xd608
movups %xmm0, 0x8(%rax)
movups 0x7760(%rip), %xmm0     # 0xd618
movups %xmm0, 0x18(%rax)
movups 0x7765(%rip), %xmm0     # 0xd628
movups %xmm0, 0x28(%rax)
movups 0x776a(%rip), %xmm0     # 0xd638
movups %xmm0, 0x38(%rax)
leaq 0x772f(%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 0x737a(%rip), %rdi      # 0xd280
movq %r15, %rsi
movq %rbx, %rdx
xorl %ecx, %ecx
callq 0x7441
movq %r12, %rdi
xorl %esi, %esi
callq 0x1990
movl %eax, %edi
callq 0x2b72
leaq 0x3d35(%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 0x76a9(%rip), %xmm0     # 0xd608
movups %xmm0, 0x8(%rax)
movups 0x76ae(%rip), %xmm0     # 0xd618
movups %xmm0, 0x18(%rax)
movups 0x76b3(%rip), %xmm0     # 0xd628
movups %xmm0, 0x28(%rax)
movups 0x76b8(%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 0x72c8(%rip), %rdi      # 0xd280
movq %r12, %rsi
movl 0x50(%rsp), %r12d
movq %r13, %rdx
xorl %ecx, %ecx
callq 0x7441
movq (%rbx), %rax
movzbl (%rax), %ecx
cmpl $0x3b, %ecx
je 0x61ef
movq %r13, 0x68(%rsp)
cmpl $0x7b, %ecx
jne 0x62c5
incq %rax
movq %rbx, 0x60(%rsp)
movq %rax, (%rbx)
movl $0x48, %edi
callq 0x1140
movq %rax, %r13
leaq 0x72ca(%rip), %rax      # 0xd2d0
movq %r13, (%rax)
leaq 0x70(%rsp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x72c8
movl $0x9, %ecx
movq %r13, %rdi
movq %rbx, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x3cb4(%rip), %rsi      # 0x9ce1
movq 0x58(%rsp), %rdi
movq %r14, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x1100
leaq 0x75c2(%rip), %rbx      # 0xd608
movq %rbx, %rdi
callq 0x7ab4
movq %rbx, %rdi
callq 0x7a9c
cmpl $0x6, %eax
je 0x615e
movq %r15, %r14
movl %r12d, %eax
movq %rax, 0x50(%rsp)
incl %ebp
decl %ebp
je 0x6207
movl %ebp, %r15d
leaq 0x7252(%rip), %rbx      # 0xd2d0
movq (%rbx), %rsi
movl $0x9, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %r14, %rdi
xorl %esi, %esi
callq 0x7389
testq %rax, %rax
jne 0x6224
movl $0x50, %edi
callq 0x1140
movq %rax, %r13
leaq 0x70(%rsp), %rdi
leaq 0x7550(%rip), %rsi      # 0xd608
callq 0x7bdc
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 0x712d(%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 0x7441
addl $0x4, (%r12)
addq 0x50(%rsp), %r14
incl 0x728a(%rip)            # 0xd3d0
leaq 0x74bb(%rip), %rdi      # 0xd608
callq 0x7a9c
cmpl $0x6, %eax
movl %r15d, %ebp
jne 0x606c
leaq 0x74a3(%rip), %rbx      # 0xd608
movq %rbx, %rdi
callq 0x7ab4
movq %rbx, %rdi
callq 0x7a9c
cmpl $0x5, %eax
movq 0x68(%rsp), %r15
je 0x62e4
movl 0x7247(%rip), %eax      # 0xd3d0
movl %eax, 0x7245(%rip)      # 0xd3d4
movq 0x60(%rsp), %r14
movq %r14, %rdi
movl $0x1, %esi
movq 0x58(%rsp), %rbx
movq %rbx, %rdx
callq 0x630a
incq (%r14)
movl 0x721e(%rip), %eax      # 0xd3d0
movl %eax, 0x4c(%r15)
movl 0x7218(%rip), %eax      # 0xd3d4
leal 0x4(,%rax,4), %edx
leaq 0x3b74(%rip), %rsi      # 0x9d3e
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1100
leaq 0x3b74(%rip), %rdi      # 0x9d4f
movl $0x7, %esi
movl $0x1, %edx
movq %rbx, %rcx
callq 0x1190
jmp 0x61f5
incq %rax
movq %rax, (%rbx)
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movups 0x3ae3(%rip), %xmm0     # 0x9cf1
movaps %xmm0, 0x72cb(%rip)     # 0xd4e0
movl $0x217374, 0x72d1(%rip) # imm = 0x217374
jmp 0x6300
movups 0x3ae3(%rip), %xmm0     # 0x9d0e
movups %xmm0, 0x72b7(%rip)     # 0xd4e9
movups 0x3acc(%rip), %xmm0     # 0x9d05
jmp 0x62f9
movups 0x39e0(%rip), %xmm0     # 0x9c25
movups %xmm0, 0x729d(%rip)     # 0xd4e9
movups 0x39c9(%rip), %xmm0     # 0x9c1c
jmp 0x62f9
movups 0x3a25(%rip), %xmm0     # 0x9c84
movaps %xmm0, 0x727a(%rip)     # 0xd4e0
movabsq $0x656d616e206e6f, %rax # imm = 0x656D616E206E6F
movq %rax, 0x7278(%rip)      # 0xd4ef
jmp 0x6300
movabsq $0x273b2720646574, %rax # imm = 0x273B2720646574
movq %rax, 0x7258(%rip)      # 0xd4e5
movabsq $0x6465746365707845, %rax # imm = 0x6465746365707845
movq %rax, 0x7242(%rip)      # 0xd4e0
jmp 0x6300
movups 0x39a9(%rip), %xmm0     # 0x9c50
movups %xmm0, 0x724d(%rip)     # 0xd4fb
movups 0x3990(%rip), %xmm0     # 0x9c45
movaps %xmm0, 0x7234(%rip)     # 0xd4f0
movups 0x3972(%rip), %xmm0     # 0x9c35
jmp 0x62f9
movsbl %cl, %ecx
leaq 0x7211(%rip), %rdi      # 0xd4e0
leaq 0x39e7(%rip), %rdx      # 0x9cbd
movl $0x100, %esi            # imm = 0x100
xorl %eax, %eax
callq 0x10c0
jmp 0x6300
movups 0x3a43(%rip), %xmm0     # 0x9d2e
movaps %xmm0, 0x71fe(%rip)     # 0xd4f0
movups 0x3a25(%rip), %xmm0     # 0x9d1e
movaps %xmm0, 0x71e0(%rip)     # 0xd4e0
movl $0x1, %edi
callq 0x5b10