// File: /workspace/github_c_makefile_star2_O3/markdryan[P]subtilis/frontend/parser_loops.c
// Function: prv_init_local_range_var
static void prv_init_local_range_var(subtilis_parser_t *p, subtilis_token_t *t,
				     subtilis_for_context_t *for_ctx,
				     const char *var_name,
				     const subtilis_type_t *type,
				     subtilis_error_t *err)
{
	const subtilis_symbol_t *s;

	if (subtilis_symbol_table_lookup(p->local_st, var_name)) {
		subtilis_error_set_already_defined(
		    err, var_name, p->l->stream->name, p->l->line);
		return;
	}

	if (subtilis_type_if_is_numeric(type) ||
	    type->type == SUBTILIS_TYPE_FN) {
		for_ctx->is_reg = true;

		subtilis_type_copy(&for_ctx->type, type, err);
		if (err->type != SUBTILIS_ERROR_OK)
			return;

		if (subtilis_type_if_reg_type(&for_ctx->type) ==
		    SUBTILIS_IR_REG_TYPE_INTEGER)
			for_ctx->loc = p->current->reg_counter++;
		else
			for_ctx->loc = p->current->freg_counter++;
		(void)subtilis_symbol_table_insert_reg(
		    p->local_st, var_name, &for_ctx->type, for_ctx->loc, err);
		return;
	} else if (type->type == SUBTILIS_TYPE_REC) {
		/*
		 * TODO: So this isn't ideal.  The range loop value
		 * variable has copy semantics, so we need to
		 * allocate a block of memory large enough to copy the
		 * loop variable.  We only really need to do this
		 * if we know that the range variable will be modified.
		 */

		subtilis_type_copy(&for_ctx->type, type, err);
		if (err->type != SUBTILIS_ERROR_OK)
			return;

		(void)subtilis_symbol_table_insert_no_rc(p->local_st, var_name,
							 &for_ctx->type, err);
		if (err->type != SUBTILIS_ERROR_OK)
			return;
	} else {
		subtilis_type_copy(&for_ctx->type, type, err);
		if (err->type != SUBTILIS_ERROR_OK)
			return;
	}

	/*
	 * There's no need to initialise the range var as its lifetime is
	 * restricted to the lifetime of the loop and it's value will be
	 * set during the first iteration.
	 */

	s = subtilis_symbol_table_insert_no_rc(p->local_st, var_name, type,
					       err);
	if (err->type != SUBTILIS_ERROR_OK)
		return;
	for_ctx->is_reg = s->is_reg;
	for_ctx->reg = SUBTILIS_IR_REG_LOCAL;
	for_ctx->loc = s->loc;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %r8, %rbx
movq %rcx, %r13
movq %rdx, %r15
movq %rsi, %r14
movq %rdi, %r12
movq 0x68(%rdi), %rdi
movq %rdx, %rsi
callq 0x2ebbc
testq %rax, %rax
je 0x23e94
movq (%r12), %rax
movq 0x30(%rax), %r8
movl 0x38(%rax), %r9d
leaq 0x4fb1e(%rip), %rax     # 0x7398c
leaq 0x4ffa0(%rip), %rcx     # 0x73e15
movq %rbx, %rdi
movl $0x20, %esi
movq %r15, %rdx
pushq $0x66e                  # imm = 0x66E
pushq %rax
callq 0x143da
addq $0x18, %rsp
jmp 0x23f8c
movq %r13, %rdi
callq 0x37534
testb %al, %al
jne 0x23eb2
movl (%r13), %eax
cmpl $0x16, %eax
je 0x23f18
cmpl $0x9, %eax
jne 0x23f44
movb $0x1, (%r14)
leaq 0x18(%r14), %rbp
movq %rbp, %rdi
movq %r13, %rsi
movq %rbx, %rdx
callq 0x2f78a
cmpl $0x0, (%rbx)
jne 0x23f88
movq %rbp, %rdi
callq 0x379a7
xorl %edx, %edx
testl %eax, %eax
setne %dl
movq 0x48(%r12), %rax
movq 0x18(%rax,%rdx,8), %rcx
leaq 0x1(%rcx), %rsi
movq %rsi, 0x18(%rax,%rdx,8)
movq %rcx, 0x10(%r14)
movq 0x68(%r12), %rdi
movq %r15, %rsi
movq %rbp, %rdx
movq %rbx, %r8
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2e922
leaq 0x18(%r14), %rbp
movq %rbp, %rdi
movq %r13, %rsi
movq %rbx, %rdx
callq 0x2f78a
cmpl $0x0, (%rbx)
jne 0x23f88
movq 0x68(%r12), %rdi
movq %r15, %rsi
movq %rbp, %rdx
movq %rbx, %rcx
callq 0x2e5cd
jmp 0x23f53
leaq 0x18(%r14), %rdi
movq %r13, %rsi
movq %rbx, %rdx
callq 0x2f78a
cmpl $0x0, (%rbx)
jne 0x23f88
movq 0x68(%r12), %rdi
movq %r15, %rsi
movq %r13, %rdx
movq %rbx, %rcx
callq 0x2e5cd
cmpl $0x0, (%rbx)
jne 0x23f88
movb 0x2a8(%rax), %cl
movb %cl, (%r14)
movq $0x2, 0x8(%r14)
movq (%rax), %rax
movq %rax, 0x10(%r14)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq