// File: /workspace/github_c_makefile_star2_O0/markdryan[P]subtilis/frontend/fn_type.c
// Function: prv_generate_zero_fn
static size_t prv_generate_zero_fn(subtilis_parser_t *p,
				   const subtilis_type_t *type,
				   subtilis_error_t *err)
{
	subtilis_type_section_t *stype;
	subtilis_buffer_t name;
	subtilis_exp_t *e;
	const char *fn_name;
	const subtilis_symbol_t *s;
	subtilis_ir_operand_t result;
	subtilis_ir_operand_t ret_reg;
	subtilis_symbol_table_t *local_st = NULL;
	size_t call_index = SIZE_MAX;
	subtilis_symbol_table_t *old_local_st = p->local_st;
	subtilis_ir_section_t *old_section = p->current;

	subtilis_buffer_init(&name, 64);

	if (type->type == SUBTILIS_TYPE_ARRAY_FN) {
		/* I need a loop here that generates functions recursively. */
		subtilis_error_set_assertion_failed(err);
		return SIZE_MAX;
	}

	local_st = subtilis_symbol_table_new(err);
	if (err->type != SUBTILIS_ERROR_OK)
		return SIZE_MAX;
	p->local_st = local_st;

	stype = subtilis_type_section_new(type, 0, NULL, NULL, err);
	if (err->type != SUBTILIS_ERROR_OK)
		goto cleanup;

	subtilis_buffer_append_string(&name, "!", err);
	if (err->type != SUBTILIS_ERROR_OK)
		goto cleanup;

	subtilis_full_type_name(type, &name, err);
	if (err->type != SUBTILIS_ERROR_OK)
		goto cleanup;

	fn_name = subtilis_buffer_get_string(&name);
	if (subtilis_string_pool_find(p->prog->string_pool, fn_name,
				      &call_index))
		goto cleanup;

	p->current = subtilis_ir_prog_section_new(
	    p->prog, fn_name, 0, stype, SUBTILIS_BUILTINS_MAX,
	    p->l->stream->name, p->l->line, p->eflag_offset, p->error_offset,
	    &call_index, err);
	stype = NULL;
	if (err->type != SUBTILIS_ERROR_OK)
		goto cleanup;

	if (type->type != SUBTILIS_TYPE_VOID) {
		if (subtilis_type_if_is_reference(type)) {
			s = subtilis_symbol_table_insert_tmp(local_st, type,
							     NULL, err);
			if (err->type != SUBTILIS_ERROR_OK)
				goto cleanup;

			subtilis_type_if_zero_ref(
			    p, type, SUBTILIS_IR_REG_LOCAL, s->loc, false, err);
			if (err->type != SUBTILIS_ERROR_OK)
				goto cleanup;

			result.reg = subtilis_reference_get_pointer(
			    p, SUBTILIS_IR_REG_LOCAL, s->loc, err);
			if (err->type != SUBTILIS_ERROR_OK)
				goto cleanup;

			/*
			 * Arrays are trickier as they don't have a zero value
			 */

			if (subtilis_type_if_is_array(type)) {
				ret_reg.reg = p->current->ret_reg;
				subtilis_ir_section_add_instr_no_reg2(
				    p->current, SUBTILIS_OP_INSTR_MOV, ret_reg,
				    result, err);
				if (err->type != SUBTILIS_ERROR_OK)
					goto cleanup;

				subtilis_ir_section_add_label(
				    p->current, p->current->end_label, err);
				if (err->type != SUBTILIS_ERROR_OK)
					goto cleanup;
			} else {
				ret_reg.reg = result.reg;
			}
			e = subtilis_exp_new_var(type, ret_reg.reg, err);
			if (err->type != SUBTILIS_ERROR_OK)
				goto cleanup;

			p->current->locals = local_st->max_allocated;
		} else {
			e = subtilis_type_if_zero(p, type, err);
		}
		if (err->type != SUBTILIS_ERROR_OK)
			goto cleanup;

		subtilis_type_if_ret(p, type, e->exp.ir_op.reg, err);
		subtilis_exp_delete(e);
	} else {
		subtilis_ir_section_add_instr_no_arg(
		    p->current, SUBTILIS_OP_INSTR_RET, err);
	}

cleanup:
	p->current = old_section;

	subtilis_type_section_delete(stype);
	p->local_st = old_local_st;
	subtilis_symbol_table_delete(local_st);
	subtilis_buffer_free(&name);

	return call_index;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
subq $0xb0, %rsp
movq %rdi, -0x20(%rbp)
movq %rsi, -0x28(%rbp)
movq %rdx, -0x30(%rbp)
movq $0x0, -0x78(%rbp)
movq $-0x1, -0x80(%rbp)
movq -0x20(%rbp), %rax
movq 0x68(%rax), %rax
movq %rax, -0x88(%rbp)
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rax
movq %rax, -0x90(%rbp)
leaq -0x48(%rbp), %rdi
movl $0x40, %esi
callq 0x15f80
movq -0x28(%rbp), %rax
cmpl $0xe, (%rax)
jne 0x5b766
movq -0x30(%rbp), %rdi
movl $0xf, %esi
leaq 0x51150(%rip), %rdx     # 0xac89f
movl $0x2d, %ecx
callq 0x158e0
movq $-0x1, -0x18(%rbp)
jmp 0x5baba
movq -0x30(%rbp), %rdi
callq 0x3c180
movq %rax, -0x78(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5b789
movq $-0x1, -0x18(%rbp)
jmp 0x5baba
movq -0x78(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x68(%rax)
movq -0x28(%rbp), %rdi
movq -0x30(%rbp), %r8
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rsi
movq %rcx, %rdx
callq 0x3dc00
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5b7be
jmp 0x5ba79
movq -0x30(%rbp), %rdx
leaq -0x48(%rbp), %rdi
leaq 0x4ed1e(%rip), %rsi     # 0xaa4eb
callq 0x16310
movq -0x30(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5b7e0
jmp 0x5ba79
movq -0x28(%rbp), %rdi
movq -0x30(%rbp), %rdx
leaq -0x48(%rbp), %rsi
callq 0x3e1f0
movq -0x30(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5b7ff
jmp 0x5ba79
leaq -0x48(%rbp), %rdi
callq 0x16760
movq %rax, -0x58(%rbp)
movq -0x20(%rbp), %rax
movq 0x58(%rax), %rax
movq 0x18(%rax), %rdi
movq -0x58(%rbp), %rsi
leaq -0x80(%rbp), %rdx
callq 0x3d5a0
testb $0x1, %al
jne 0x5b82b
jmp 0x5b830
jmp 0x5ba79
movq -0x20(%rbp), %rax
movq 0x58(%rax), %rdi
movq -0x58(%rbp), %rsi
movq -0x38(%rbp), %rcx
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq 0x30(%rax), %r9
movq -0x20(%rbp), %rax
movq (%rax), %rax
movl 0x38(%rax), %eax
movl %eax, %r14d
movq -0x20(%rbp), %rax
movl 0xb0(%rax), %ebx
movq -0x20(%rbp), %rax
movl 0xb4(%rax), %r11d
movq -0x30(%rbp), %rax
xorl %edx, %edx
movl $0x9, %r8d
leaq -0x80(%rbp), %r10
movq %r14, (%rsp)
movl %ebx, 0x8(%rsp)
movl %r11d, 0x10(%rsp)
movq %r10, 0x18(%rsp)
movq %rax, 0x20(%rsp)
callq 0x38bd0
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x48(%rax)
movq $0x0, -0x38(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5b8ba
jmp 0x5ba79
movq -0x28(%rbp), %rax
cmpl $0x8, (%rax)
je 0x5ba61
movq -0x28(%rbp), %rdi
callq 0x4a090
testb $0x1, %al
jne 0x5b8d9
jmp 0x5ba1a
movq -0x78(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rcx
xorl %eax, %eax
movl %eax, %edx
callq 0x3c920
movq %rax, -0x60(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5b900
jmp 0x5ba79
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x60(%rbp), %rax
movq (%rax), %rcx
movq -0x30(%rbp), %r9
movl $0x2, %edx
xorl %r8d, %r8d
callq 0x47600
movq -0x30(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5b92e
jmp 0x5ba79
movq -0x20(%rbp), %rdi
movq -0x60(%rbp), %rax
movq (%rax), %rdx
movq -0x30(%rbp), %rcx
movl $0x2, %esi
callq 0x6d920
movq %rax, -0x68(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5b959
jmp 0x5ba79
movq -0x28(%rbp), %rdi
callq 0x49ff0
testb $0x1, %al
jne 0x5b968
jmp 0x5b9d7
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rax
movq 0xa8(%rax), %rax
movq %rax, -0x70(%rbp)
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
movq -0x30(%rbp), %r8
movq -0x70(%rbp), %rdx
movq -0x68(%rbp), %rcx
movl $0x1d, %esi
callq 0x385a0
movq -0x30(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5b9a7
jmp 0x5ba79
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rax
movq 0x98(%rax), %rsi
movq -0x30(%rbp), %rdx
callq 0x39960
movq -0x30(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5b9d5
jmp 0x5ba79
jmp 0x5b9df
movq -0x68(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x28(%rbp), %rdi
movq -0x70(%rbp), %rax
movl %eax, %esi
movq -0x30(%rbp), %rdx
callq 0x37590
movq %rax, -0x50(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5ba01
jmp 0x5ba79
movq -0x78(%rbp), %rax
movq 0x310(%rax), %rcx
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rax
movq %rcx, 0x10(%rax)
jmp 0x5ba2f
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x47580
movq %rax, -0x50(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5ba3a
jmp 0x5ba79
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x50(%rbp), %rax
movq 0x148(%rax), %rdx
movq -0x30(%rbp), %rcx
callq 0x49e90
movq -0x50(%rbp), %rdi
callq 0x36ee0
jmp 0x5ba77
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
movq -0x30(%rbp), %rdx
movl $0x46, %esi
callq 0x385f0
jmp 0x5ba79
movq -0x90(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x48(%rax)
movq -0x38(%rbp), %rdi
callq 0x3e040
movq -0x88(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x68(%rax)
movq -0x78(%rbp), %rdi
callq 0x3c2b0
leaq -0x48(%rbp), %rdi
callq 0x16650
movq -0x80(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
addq $0xb0, %rsp
popq %rbx
popq %r14
popq %rbp
retq
nopw (%rax,%rax)