// File: /workspace/github_c_makefile_star2_O0/been-jamming[P]MinimalCC/expression.c
// Function: compile_function_call
void compile_function_call(char **c, value *func, FILE *output_file){
	reg_list reg_state;
	data_entry return_data;
	data_entry return_address_data;
	type current_argument_type;
	value current_argument_value;
	unsigned int label_num;
	int func_stack_pos = 0;
	int any_args = 0;

	if(peek_type(&(func->data_type)) == type_pointer){
		pop_type(&(func->data_type));
	}
	if(pop_type(&(func->data_type)) != type_function){
		snprintf(error_message, sizeof(error_message), "Can't call non-function type");
		do_error(1);
	}

	label_num = num_labels;
	num_labels++;
	reg_state = push_registers(output_file);

	if(func->data.type == data_register){
		func_stack_pos = get_reg_stack_pos(reg_state, func->data.reg);
	}
	return_address_data = allocate(1);
	return_data = allocate(1);
	fileprint(output_file, "la $t0, __L%d\n", label_num);
	fileprint(output_file, "sw $t0, %d($sp)\n", get_stack_pos(return_address_data));
	if(peek_type(&(func->data_type)) == type_returns){
		skip_whitespace(c);
		if(**c != ')'){
			snprintf(error_message, sizeof(error_message), "Expected ')'");
			do_error(1);
		}
		++*c;
	}
	while(peek_type(&(func->data_type)) != type_returns){
		any_args = 1;
		current_argument_type = get_argument_type(&(func->data_type));
		compile_expression(&current_argument_value, c, 1, 1, output_file);
		if(**c != ',' && peek_type(&(func->data_type)) != type_returns){
			snprintf(error_message, sizeof(error_message), "Expected ','");
			do_error(1);
		} else if(**c != ')' && peek_type(&(func->data_type)) == type_returns){
			snprintf(error_message, sizeof(error_message), "Expected ')'");
			do_error(1);
		}
		++*c;
		cast(&current_argument_value, current_argument_type, 1, output_file);
	}

	pop_type(&(func->data_type));
	if(func->data.type == data_register){
		fileprint(output_file, "lw $t0, %d($sp)\n", func_stack_pos);
		if(any_args)
			fileprint(output_file, "addi $sp, $sp, %d\n", get_stack_pos(current_argument_value.data));
		else
			fileprint(output_file, "addi $sp, $sp, %d\n", get_stack_pos(return_data));
		fileprint(output_file, "jr $t0\n\n");
	} else if(func->data.type == data_stack){
		fileprint(output_file, "lw $t0, %d($sp)\n", get_stack_pos(func->data));
		if(any_args)
			fileprint(output_file, "addi $sp, $sp, %d\n", get_stack_pos(current_argument_value.data));
		else
			fileprint(output_file, "addi $sp, $sp, %d\n", get_stack_pos(return_data));
		fileprint(output_file, "jr $t0\n\n");
	}
	fileprint(output_file, "__L%d:\n", label_num);
	if(any_args)
		fileprint(output_file, "addi $sp, $sp, %d\n", -get_stack_pos(current_argument_value.data));
	else
		fileprint(output_file, "addi $sp, $sp, %d\n", -get_stack_pos(return_data));
	fileprint(output_file, "lw $t0, %d($sp)\n", get_stack_pos(return_data));
	deallocate(return_data);
	deallocate(return_address_data);
	pull_registers(reg_state, output_file);
	if(func->data.type == data_register){
		fileprint(output_file, "move $s%d, $t0\n", func->data.reg);
	} else if(func->data.type == data_stack){
		fileprint(output_file, "sw $t0, %d($sp)\n", get_stack_pos(func->data));
	}
}

// Assembly:
subq $0x2d8, %rsp            # imm = 0x2D8
movq %rdi, 0x2d0(%rsp)
movq %rsi, 0x2c8(%rsp)
movq %rdx, 0x2c0(%rsp)
movl $0x0, 0x1f0(%rsp)
movl $0x0, 0x1ec(%rsp)
movq 0x2c8(%rsp), %rdi
addq $0x10, %rdi
callq 0xbdb0
cmpl $0x4, %eax
jne 0x474c
movq 0x2c8(%rsp), %rdi
addq $0x10, %rdi
callq 0xbe20
movq 0x2c8(%rsp), %rdi
addq $0x10, %rdi
callq 0xbe20
cmpl $0x5, %eax
je 0x4786
leaq 0xcdc7(%rip), %rdi      # 0x11530
movl $0x100, %esi            # imm = 0x100
leaq 0x922d(%rip), %rdx      # 0xd9a2
movb $0x0, %al
callq 0x10b0
movl $0x1, %edi
callq 0x87b0
movl 0xcb34(%rip), %eax      # 0x112c0
movl %eax, 0x1f4(%rsp)
movl 0xcb27(%rip), %eax      # 0x112c0
addl $0x1, %eax
movl %eax, 0xcb1e(%rip)      # 0x112c0
movq 0x2c0(%rsp), %rsi
leaq 0x1d8(%rsp), %rdi
callq 0x14e0
movq 0x1d8(%rsp), %rax
movq %rax, 0x2a8(%rsp)
movq 0x1e0(%rsp), %rax
movq %rax, 0x2b0(%rsp)
movl 0x1e8(%rsp), %eax
movl %eax, 0x2b8(%rsp)
movq 0x2c8(%rsp), %rax
cmpl $0x0, (%rax)
jne 0x482b
movq 0x2c8(%rsp), %rax
movl 0x4(%rax), %eax
leaq 0x2a8(%rsp), %rcx
movq (%rcx), %rdx
movq %rdx, (%rsp)
movq 0x8(%rcx), %rdx
movq %rdx, 0x8(%rsp)
movl 0x10(%rcx), %ecx
movl %ecx, 0x10(%rsp)
movzbl %al, %edi
callq 0x15d0
movl %eax, 0x1f0(%rsp)
movl $0x1, %edi
movl %edi, 0x8c(%rsp)
callq 0x1300
movl 0x8c(%rsp), %edi
movl %edx, 0x1c0(%rsp)
movq %rax, 0x1b8(%rsp)
movl 0x1c0(%rsp), %eax
movl %eax, 0x1d0(%rsp)
movq 0x1b8(%rsp), %rax
movq %rax, 0x1c8(%rsp)
movl 0x1d0(%rsp), %eax
movl %eax, 0x298(%rsp)
movq 0x1c8(%rsp), %rax
movq %rax, 0x290(%rsp)
callq 0x1300
movl %edx, 0x1a0(%rsp)
movq %rax, 0x198(%rsp)
movq 0x198(%rsp), %rax
movq %rax, 0x1ac(%rsp)
movl 0x1a0(%rsp), %eax
movl %eax, 0x1b4(%rsp)
movq 0x1ac(%rsp), %rax
movq %rax, 0x29c(%rsp)
movl 0x1b4(%rsp), %eax
movl %eax, 0x2a4(%rsp)
movq 0x2c0(%rsp), %rdi
movl 0x1f4(%rsp), %edx
leaq 0x90cb(%rip), %rsi      # 0xd9bf
movb $0x0, %al
callq 0x16f0
movq 0x2c0(%rsp), %rax
movq %rax, 0x90(%rsp)
movq 0x290(%rsp), %rax
movq %rax, 0x188(%rsp)
movl 0x298(%rsp), %eax
movl %eax, 0x190(%rsp)
movq 0x188(%rsp), %rdi
movl 0x190(%rsp), %esi
callq 0x1490
movq 0x90(%rsp), %rdi
movl %eax, %edx
leaq 0x8e8b(%rip), %rsi      # 0xd7d9
movb $0x0, %al
callq 0x16f0
movq 0x2c8(%rsp), %rdi
addq $0x10, %rdi
callq 0xbdb0
cmpl $0x6, %eax
jne 0x49c1
movq 0x2d0(%rsp), %rdi
callq 0xbb70
movq 0x2d0(%rsp), %rax
movq (%rax), %rax
movsbl (%rax), %eax
cmpl $0x29, %eax
je 0x49af
leaq 0xcb9e(%rip), %rdi      # 0x11530
movl $0x100, %esi            # imm = 0x100
leaq 0x9030(%rip), %rdx      # 0xd9ce
movb $0x0, %al
callq 0x10b0
movl $0x1, %edi
callq 0x87b0
movq 0x2d0(%rsp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
jmp 0x49c3
movq 0x2c8(%rsp), %rdi
addq $0x10, %rdi
callq 0xbdb0
cmpl $0x6, %eax
je 0x4b40
movl $0x1, 0x1ec(%rsp)
movq 0x2c8(%rsp), %rsi
addq $0x10, %rsi
leaq 0x148(%rsp), %rdi
callq 0xc090
leaq 0x250(%rsp), %rdi
leaq 0x148(%rsp), %rsi
movl $0x40, %edx
callq 0x1120
movq 0x2d0(%rsp), %rsi
movq 0x2c0(%rsp), %r8
leaq 0x1f8(%rsp), %rdi
movl $0x1, %ecx
movl %ecx, %edx
callq 0x4fe0
movq 0x2d0(%rsp), %rax
movq (%rax), %rax
movsbl (%rax), %eax
cmpl $0x2c, %eax
je 0x4a8e
movq 0x2c8(%rsp), %rdi
addq $0x10, %rdi
callq 0xbdb0
cmpl $0x6, %eax
je 0x4a8e
leaq 0xcac1(%rip), %rdi      # 0x11530
movl $0x100, %esi            # imm = 0x100
leaq 0x8f60(%rip), %rdx      # 0xd9db
movb $0x0, %al
callq 0x10b0
movl $0x1, %edi
callq 0x87b0
jmp 0x4add
movq 0x2d0(%rsp), %rax
movq (%rax), %rax
movsbl (%rax), %eax
cmpl $0x29, %eax
je 0x4adb
movq 0x2c8(%rsp), %rdi
addq $0x10, %rdi
callq 0xbdb0
cmpl $0x6, %eax
jne 0x4adb
leaq 0xca72(%rip), %rdi      # 0x11530
movl $0x100, %esi            # imm = 0x100
leaq 0x8f04(%rip), %rdx      # 0xd9ce
movb $0x0, %al
callq 0x10b0
movl $0x1, %edi
callq 0x87b0
jmp 0x4add
movq 0x2d0(%rsp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movq 0x2c0(%rsp), %rdx
movups 0x250(%rsp), %xmm0
movups 0x260(%rsp), %xmm1
movups 0x270(%rsp), %xmm2
movups 0x280(%rsp), %xmm3
movq %rsp, %rax
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
leaq 0x1f8(%rsp), %rdi
movl $0x1, %esi
callq 0x3fd0
jmp 0x49c3
movq 0x2c8(%rsp), %rdi
addq $0x10, %rdi
callq 0xbe20
movq 0x2c8(%rsp), %rax
cmpl $0x0, (%rax)
jne 0x4c54
movq 0x2c0(%rsp), %rdi
movl 0x1f0(%rsp), %edx
leaq 0x8cf2(%rip), %rsi      # 0xd86a
movb $0x0, %al
callq 0x16f0
cmpl $0x0, 0x1ec(%rsp)
je 0x4be5
movq 0x2c0(%rsp), %rax
movq %rax, 0x80(%rsp)
movq 0x1f8(%rsp), %rax
movq %rax, 0x138(%rsp)
movl 0x200(%rsp), %eax
movl %eax, 0x140(%rsp)
movq 0x138(%rsp), %rdi
movl 0x140(%rsp), %esi
callq 0x1490
movq 0x80(%rsp), %rdi
movl %eax, %edx
leaq 0x8e0c(%rip), %rsi      # 0xd9e8
movb $0x0, %al
callq 0x16f0
jmp 0x4c39
movq 0x2c0(%rsp), %rax
movq %rax, 0x78(%rsp)
movq 0x29c(%rsp), %rax
movq %rax, 0x128(%rsp)
movl 0x2a4(%rsp), %eax
movl %eax, 0x130(%rsp)
movq 0x128(%rsp), %rdi
movl 0x130(%rsp), %esi
callq 0x1490
movq 0x78(%rsp), %rdi
movl %eax, %edx
leaq 0x8db6(%rip), %rsi      # 0xd9e8
movb $0x0, %al
callq 0x16f0
movq 0x2c0(%rsp), %rdi
leaq 0x8db3(%rip), %rsi      # 0xd9fb
movb $0x0, %al
callq 0x16f0
jmp 0x4d84
movq 0x2c8(%rsp), %rax
cmpl $0x1, (%rax)
jne 0x4d82
movq 0x2c0(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x2c8(%rsp), %rax
movq (%rax), %rcx
movq %rcx, 0x118(%rsp)
movl 0x8(%rax), %eax
movl %eax, 0x120(%rsp)
movq 0x118(%rsp), %rdi
movl 0x120(%rsp), %esi
callq 0x1490
movq 0x70(%rsp), %rdi
movl %eax, %edx
leaq 0x8bb9(%rip), %rsi      # 0xd86a
movb $0x0, %al
callq 0x16f0
cmpl $0x0, 0x1ec(%rsp)
je 0x4d18
movq 0x2c0(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x1f8(%rsp), %rax
movq %rax, 0x108(%rsp)
movl 0x200(%rsp), %eax
movl %eax, 0x110(%rsp)
movq 0x108(%rsp), %rdi
movl 0x110(%rsp), %esi
callq 0x1490
movq 0x68(%rsp), %rdi
movl %eax, %edx
leaq 0x8cd9(%rip), %rsi      # 0xd9e8
movb $0x0, %al
callq 0x16f0
jmp 0x4d6c
movq 0x2c0(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x29c(%rsp), %rax
movq %rax, 0xf8(%rsp)
movl 0x2a4(%rsp), %eax
movl %eax, 0x100(%rsp)
movq 0xf8(%rsp), %rdi
movl 0x100(%rsp), %esi
callq 0x1490
movq 0x60(%rsp), %rdi
movl %eax, %edx
leaq 0x8c83(%rip), %rsi      # 0xd9e8
movb $0x0, %al
callq 0x16f0
movq 0x2c0(%rsp), %rdi
leaq 0x8c80(%rip), %rsi      # 0xd9fb
movb $0x0, %al
callq 0x16f0
jmp 0x4d84
movq 0x2c0(%rsp), %rdi
movl 0x1f4(%rsp), %edx
leaq 0x9208(%rip), %rsi      # 0xdfa2
movb $0x0, %al
callq 0x16f0
cmpl $0x0, 0x1ec(%rsp)
je 0x4e03
movq 0x2c0(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0x1f8(%rsp), %rax
movq %rax, 0xe8(%rsp)
movl 0x200(%rsp), %eax
movl %eax, 0xf0(%rsp)
movq 0xe8(%rsp), %rdi
movl 0xf0(%rsp), %esi
callq 0x1490
movq 0x58(%rsp), %rdi
xorl %edx, %edx
subl %eax, %edx
leaq 0x8bee(%rip), %rsi      # 0xd9e8
movb $0x0, %al
callq 0x16f0
jmp 0x4e59
movq 0x2c0(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x29c(%rsp), %rax
movq %rax, 0xd8(%rsp)
movl 0x2a4(%rsp), %eax
movl %eax, 0xe0(%rsp)
movq 0xd8(%rsp), %rdi
movl 0xe0(%rsp), %esi
callq 0x1490
movq 0x50(%rsp), %rdi
xorl %edx, %edx
subl %eax, %edx
leaq 0x8b96(%rip), %rsi      # 0xd9e8
movb $0x0, %al
callq 0x16f0
movq 0x2c0(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x29c(%rsp), %rax
movq %rax, 0xc8(%rsp)
movl 0x2a4(%rsp), %eax
movl %eax, 0xd0(%rsp)
movq 0xc8(%rsp), %rdi
movl 0xd0(%rsp), %esi
callq 0x1490
movq 0x48(%rsp), %rdi
movl %eax, %edx
leaq 0x89c4(%rip), %rsi      # 0xd86a
movb $0x0, %al
callq 0x16f0
movq 0x29c(%rsp), %rax
movq %rax, 0xb8(%rsp)
movl 0x2a4(%rsp), %eax
movl %eax, 0xc0(%rsp)
movq 0xb8(%rsp), %rdi
movl 0xc0(%rsp), %esi
callq 0x13b0
movq 0x290(%rsp), %rax
movq %rax, 0xa8(%rsp)
movl 0x298(%rsp), %eax
movl %eax, 0xb0(%rsp)
movq 0xa8(%rsp), %rdi
movl 0xb0(%rsp), %esi
callq 0x13b0
movq 0x2c0(%rsp), %rdi
leaq 0x2a8(%rsp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movl 0x10(%rax), %eax
movl %eax, 0x10(%rsp)
callq 0x1610
movq 0x2c8(%rsp), %rax
cmpl $0x0, (%rax)
jne 0x4f6d
movq 0x2c0(%rsp), %rdi
movq 0x2c8(%rsp), %rax
movl 0x4(%rax), %edx
leaq 0x8aa0(%rip), %rsi      # 0xda04
movb $0x0, %al
callq 0x16f0
jmp 0x4fcf
movq 0x2c8(%rsp), %rax
cmpl $0x1, (%rax)
jne 0x4fcd
movq 0x2c0(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x2c8(%rsp), %rax
movq (%rax), %rcx
movq %rcx, 0x98(%rsp)
movl 0x8(%rax), %eax
movl %eax, 0xa0(%rsp)
movq 0x98(%rsp), %rdi
movl 0xa0(%rsp), %esi
callq 0x1490
movq 0x40(%rsp), %rdi
movl %eax, %edx
leaq 0x8813(%rip), %rsi      # 0xd7d9
movb $0x0, %al
callq 0x16f0
jmp 0x4fcf
addq $0x2d8, %rsp            # imm = 0x2D8
retq
nopw (%rax,%rax)