// File: /workspace/github_c_makefile_star2_O0/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:
subq $0x138, %rsp            # imm = 0x138
movq %rdi, 0x130(%rsp)
movq %rsi, 0x128(%rsp)
movq %rdx, 0x120(%rsp)
movl %ecx, 0x11c(%rsp)
movl %r8d, 0x118(%rsp)
movq %r9, 0x110(%rsp)
movl $0x0, 0xfc(%rsp)
movl $0x0, 0x89b5(%rip)      # 0x11420
leaq 0x8826(%rip), %rax      # 0x11298
movl $0x0, (%rax)
leaq 0x8bd9(%rip), %rdi      # 0x11658
leaq 0x8d22(%rip), %rsi      # 0x117a8
movl $0x40, %edx
callq 0x1120
movq 0x130(%rsp), %rsi
movq 0x128(%rsp), %rdx
movq 0x120(%rsp), %rcx
movl 0x11c(%rsp), %r8d
movl 0x118(%rsp), %r9d
leaq 0x8b99(%rip), %rdi      # 0x11658
callq 0xc370
cmpq $0x0, 0x128(%rsp)
jne 0x8af3
leaq 0x8a5a(%rip), %rdi      # 0x11530
movl $0x100, %esi            # imm = 0x100
leaq 0x533e(%rip), %rdx      # 0xde20
movb $0x0, %al
callq 0x10b0
movl $0x1, %edi
callq 0x87b0
movq 0x130(%rsp), %rdi
callq 0xbb70
leaq 0x8b51(%rip), %rdi      # 0x11658
callq 0xbdb0
cmpl $0x5, %eax
je 0x8ccc
movq 0x130(%rsp), %rdi
callq 0xbb70
movq 0x130(%rsp), %rax
movq (%rax), %rax
movsbl (%rax), %eax
cmpl $0x3b, %eax
je 0x8b59
leaq 0x89f4(%rip), %rdi      # 0x11530
movl $0x100, %esi            # imm = 0x100
leaq 0x4c6c(%rip), %rdx      # 0xd7b4
movb $0x0, %al
callq 0x10b0
movl $0x1, %edi
callq 0x87b0
movq 0x130(%rsp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movq 0x128(%rsp), %rdi
xorl %eax, %eax
leaq 0x8754(%rip), %rcx      # 0x112d0
movq 0x40(%rcx), %rdx
movq %rsp, %rax
movq %rdx, 0x40(%rax)
movups (%rcx), %xmm0
movups 0x10(%rcx), %xmm1
movups 0x20(%rcx), %xmm2
movups 0x30(%rcx), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
xorl %esi, %esi
callq 0xb090
movq %rax, 0x108(%rsp)
cmpq $0x0, 0x108(%rsp)
je 0x8be3
leaq 0x896a(%rip), %rdi      # 0x11530
movl $0x100, %esi            # imm = 0x100
leaq 0x5267(%rip), %rdx      # 0xde39
movb $0x0, %al
callq 0x10b0
movl $0x1, %edi
callq 0x87b0
movl $0x50, %edi
callq 0x1130
movq %rax, 0x108(%rsp)
movq 0x108(%rsp), %rdi
addq $0x8, %rdi
leaq 0x8a50(%rip), %rsi      # 0x11658
movl $0x40, %edx
callq 0x1120
movq 0x128(%rsp), %rdi
callq 0x1080
movq %rax, %rdi
addq $0x1, %rdi
callq 0x1130
movq %rax, %rcx
movq 0x108(%rsp), %rax
movq %rcx, (%rax)
movq 0x108(%rsp), %rax
movb $0x0, 0x48(%rax)
movq 0x108(%rsp), %rax
movq (%rax), %rdi
movq 0x128(%rsp), %rsi
callq 0x1050
movq 0x108(%rsp), %rax
movq (%rax), %rsi
movq 0x108(%rsp), %rdx
leaq 0x8659(%rip), %rdi      # 0x112d0
xorl %ecx, %ecx
callq 0xb1e0
movq 0x110(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x128(%rsp), %rax
movq %rax, 0x68(%rsp)
leaq 0x89b9(%rip), %rdi      # 0x11658
xorl %esi, %esi
callq 0x1a40
movl %eax, %edi
callq 0x3050
movq 0x60(%rsp), %rdi
movq 0x68(%rsp), %rdx
movl %eax, %ecx
leaq 0x51a4(%rip), %rsi      # 0xde64
movb $0x0, %al
callq 0x10f0
jmp 0x91c3
movq 0x128(%rsp), %rax
cmpb $0x0, (%rax)
jne 0x8cfd
leaq 0x8850(%rip), %rdi      # 0x11530
movl $0x100, %esi            # imm = 0x100
leaq 0x519c(%rip), %rdx      # 0xde88
movb $0x0, %al
callq 0x10b0
movl $0x1, %edi
callq 0x87b0
movq 0x128(%rsp), %rdi
xorl %eax, %eax
leaq 0x85c2(%rip), %rcx      # 0x112d0
movq 0x40(%rcx), %rdx
movq %rsp, %rax
movq %rdx, 0x40(%rax)
movups (%rcx), %xmm0
movups 0x10(%rcx), %xmm1
movups 0x20(%rcx), %xmm2
movups 0x30(%rcx), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
xorl %esi, %esi
callq 0xb090
movq %rax, 0x108(%rsp)
cmpq $0x0, 0x108(%rsp)
jne 0x8df2
movl $0x50, %edi
callq 0x1130
movq %rax, 0x108(%rsp)
movq 0x108(%rsp), %rdi
addq $0x8, %rdi
leaq 0x88de(%rip), %rsi      # 0x11658
movl $0x40, %edx
callq 0x1120
movq 0x128(%rsp), %rdi
callq 0x1080
movq %rax, %rdi
addq $0x1, %rdi
callq 0x1130
movq %rax, %rcx
movq 0x108(%rsp), %rax
movq %rcx, (%rax)
movq 0x108(%rsp), %rax
movb $0x1, 0x48(%rax)
movq 0x108(%rsp), %rax
movq (%rax), %rdi
movq 0x128(%rsp), %rsi
callq 0x1050
movq 0x108(%rsp), %rax
movq (%rax), %rsi
movq 0x108(%rsp), %rdx
leaq 0x84e7(%rip), %rdi      # 0x112d0
xorl %ecx, %ecx
callq 0xb1e0
jmp 0x8e34
movq 0x108(%rsp), %rdi
addq $0x8, %rdi
leaq 0x8853(%rip), %rsi      # 0x11658
callq 0xbec0
cmpb $0x0, %al
jne 0x8e32
leaq 0x871b(%rip), %rdi      # 0x11530
movl $0x100, %esi            # imm = 0x100
leaq 0x507e(%rip), %rdx      # 0xde9f
movb $0x0, %al
callq 0x10b0
movl $0x1, %edi
callq 0x87b0
jmp 0x8e34
movq 0x130(%rsp), %rax
movq (%rax), %rax
movsbl (%rax), %eax
cmpl $0x7b, %eax
je 0x8ea3
movq 0x130(%rsp), %rax
movq (%rax), %rax
movsbl (%rax), %eax
cmpl $0x3b, %eax
je 0x8e8c
movq 0x130(%rsp), %rax
movq (%rax), %rax
movsbl (%rax), %ecx
leaq 0x86c1(%rip), %rdi      # 0x11530
movl $0x100, %esi            # imm = 0x100
leaq 0x5046(%rip), %rdx      # 0xdec1
movb $0x0, %al
callq 0x10b0
movl $0x1, %edi
callq 0x87b0
movq 0x130(%rsp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
jmp 0x91c3
movq 0x130(%rsp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movl $0x48, %edi
callq 0x1130
movq %rax, %rcx
leaq 0x8457(%rip), %rax      # 0x11320
movq %rcx, (%rax)
leaq 0x844d(%rip), %rax      # 0x11320
movq (%rax), %rax
movq %rax, 0x58(%rsp)
leaq 0xb0(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xaf20
movq 0x58(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
movl $0x48, %edx
callq 0x1120
movq 0x110(%rsp), %rdi
movq 0x128(%rsp), %rdx
movq 0x128(%rsp), %rcx
leaq 0x4fc3(%rip), %rsi      # 0xdee5
movb $0x0, %al
callq 0x10f0
leaq 0x8728(%rip), %rdi      # 0x11658
callq 0xbe20
leaq 0x871c(%rip), %rdi      # 0x11658
callq 0xbdb0
cmpl $0x6, %eax
je 0x9101
movl 0xfc(%rsp), %eax
cmpl 0x118(%rsp), %eax
jb 0x8f7e
leaq 0x85cf(%rip), %rdi      # 0x11530
movl $0x100, %esi            # imm = 0x100
leaq 0x4f88(%rip), %rdx      # 0xdef5
movb $0x0, %al
callq 0x10b0
movl $0x1, %edi
callq 0x87b0
leaq 0x839b(%rip), %rax      # 0x11320
movq (%rax), %rcx
movq 0x120(%rsp), %rdi
xorl %eax, %eax
movq 0x40(%rcx), %rdx
movq %rsp, %rax
movq %rdx, 0x40(%rax)
movups (%rcx), %xmm0
movups 0x10(%rcx), %xmm1
movups 0x20(%rcx), %xmm2
movups 0x30(%rcx), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
xorl %esi, %esi
callq 0xb090
cmpq $0x0, %rax
je 0x8fec
leaq 0x8561(%rip), %rdi      # 0x11530
movl $0x100, %esi            # imm = 0x100
leaq 0x4f2e(%rip), %rdx      # 0xdf09
movb $0x0, %al
callq 0x10b0
movl $0x1, %edi
callq 0x87b0
movl $0x50, %edi
callq 0x1130
movq %rax, 0x100(%rsp)
movq 0x100(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x50(%rsp)
leaq 0x70(%rsp), %rdi
leaq 0x863d(%rip), %rsi      # 0x11658
callq 0xc090
movq 0x50(%rsp), %rdi
leaq 0x70(%rsp), %rsi
movl $0x40, %edx
callq 0x1120
movq 0x120(%rsp), %rdi
callq 0x1080
movq %rax, %rdi
addq $0x1, %rdi
callq 0x1130
movq %rax, %rcx
movq 0x100(%rsp), %rax
movq %rcx, (%rax)
movq 0x100(%rsp), %rax
movq (%rax), %rdi
movq 0x120(%rsp), %rsi
callq 0x1050
leaq 0x821e(%rip), %rax      # 0x11298
movl (%rax), %ecx
movq 0x100(%rsp), %rax
movl %ecx, 0x48(%rax)
leaq 0x8292(%rip), %rax      # 0x11320
movq (%rax), %rdi
movq 0x100(%rsp), %rax
movq (%rax), %rsi
movq 0x100(%rsp), %rdx
xorl %ecx, %ecx
callq 0xb1e0
leaq 0x81e6(%rip), %rax      # 0x11298
movl (%rax), %ecx
addl $0x4, %ecx
leaq 0x81da(%rip), %rax      # 0x11298
movl %ecx, (%rax)
movl 0x11c(%rsp), %ecx
movq 0x120(%rsp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, 0x120(%rsp)
movl 0xfc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xfc(%rsp)
movl 0x832d(%rip), %eax      # 0x11420
addl $0x1, %eax
movl %eax, 0x8324(%rip)      # 0x11420
jmp 0x8f35
leaq 0x8550(%rip), %rdi      # 0x11658
callq 0xbe20
leaq 0x8544(%rip), %rdi      # 0x11658
callq 0xbdb0
cmpl $0x5, %eax
jne 0x9142
leaq 0x840b(%rip), %rdi      # 0x11530
movl $0x100, %esi            # imm = 0x100
leaq 0x4df1(%rip), %rdx      # 0xdf22
movb $0x0, %al
callq 0x10b0
movl $0x1, %edi
callq 0x87b0
movl 0x82d8(%rip), %eax      # 0x11420
movl %eax, 0x82d6(%rip)      # 0x11424
movq 0x130(%rsp), %rdi
movq 0x110(%rsp), %rdx
movl $0x1, %esi
callq 0x91d0
movq 0x130(%rsp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movl 0x82a0(%rip), %ecx      # 0x11420
movq 0x108(%rsp), %rax
movl %ecx, 0x4c(%rax)
movq 0x110(%rsp), %rdi
movl 0x828b(%rip), %edx      # 0x11424
shll $0x2, %edx
addl $0x4, %edx
leaq 0x4d9c(%rip), %rsi      # 0xdf42
movb $0x0, %al
callq 0x10f0
movq 0x110(%rsp), %rdi
leaq 0x4d97(%rip), %rsi      # 0xdf53
movb $0x0, %al
callq 0x10f0
addq $0x138, %rsp            # imm = 0x138
retq
nopl (%rax,%rax)