// File: /workspace/github_c_makefile_star2_O2/markdryan[P]subtilis/frontend/array_type.c
// Function: prv_new_ref_base
static size_t prv_new_ref_base(subtilis_parser_t *p, const subtilis_type_t *t,
			       subtilis_ir_operand_t dest_reg,
			       size_t dest_offset,
			       subtilis_ir_operand_t source_reg,
			       size_t source_offset, bool ref,
			       subtilis_error_t *err)
{
	subtilis_ir_operand_t soffset;
	subtilis_ir_operand_t doffset;
	subtilis_ir_operand_t ref_start;
	subtilis_ir_operand_t size;
	subtilis_ir_operand_t data;
	subtilis_ir_operand_t heap;
	subtilis_ir_operand_t ref_label;
	subtilis_ir_operand_t skip_ref_label;
	size_t i;
	bool check_size = false;

	skip_ref_label.label = SIZE_MAX;

	/* TODO: This is platform specific */

	/* copy destructor + array dimensions */

	size_t ints_to_copy = 1 + (t->params.array.num_dims);

	if (subtilis_type_if_is_vector(t)) {
		check_size = true;
		ref_label.label = subtilis_ir_section_new_label(p->current);
		skip_ref_label.label =
		    subtilis_ir_section_new_label(p->current);
	}

	soffset.integer = SUBTIILIS_ARRAY_SIZE_OFF + source_offset;
	doffset.integer = SUBTIILIS_ARRAY_SIZE_OFF + dest_offset;

	if (doffset.integer > 0) {
		ref_start.reg = subtilis_ir_section_add_instr(
		    p->current, SUBTILIS_OP_INSTR_ADDI_I32, dest_reg, doffset,
		    err);
		if (err->type != SUBTILIS_ERROR_OK)
			return SIZE_MAX;
	} else {
		ref_start = dest_reg;
	}

	size.reg = subtilis_ir_section_add_instr(
	    p->current, SUBTILIS_OP_INSTR_LOADO_I32, source_reg, soffset, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return SIZE_MAX;
	subtilis_ir_section_add_instr_reg(p->current,
					  SUBTILIS_OP_INSTR_STOREO_I32, size,
					  dest_reg, doffset, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return SIZE_MAX;

	soffset.integer += sizeof(int32_t);
	doffset.integer += sizeof(int32_t);

	if (check_size) {
		subtilis_ir_section_add_instr_reg(
		    p->current, SUBTILIS_OP_INSTR_JMPC, size, ref_label,
		    skip_ref_label, err);
		if (err->type != SUBTILIS_ERROR_OK)
			return SIZE_MAX;
		subtilis_ir_section_add_label(p->current, ref_label.label, err);
		if (err->type != SUBTILIS_ERROR_OK)
			return SIZE_MAX;
	}

	data.reg = subtilis_ir_section_add_instr(
	    p->current, SUBTILIS_OP_INSTR_LOADO_I32, source_reg, soffset, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return SIZE_MAX;
	subtilis_ir_section_add_instr_reg(p->current,
					  SUBTILIS_OP_INSTR_STOREO_I32, data,
					  dest_reg, doffset, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return SIZE_MAX;

	soffset.integer += sizeof(int32_t);
	doffset.integer += sizeof(int32_t);

	heap.reg = subtilis_ir_section_add_instr(
	    p->current, SUBTILIS_OP_INSTR_LOADO_I32, source_reg, soffset, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return SIZE_MAX;
	subtilis_ir_section_add_instr_reg(p->current,
					  SUBTILIS_OP_INSTR_STOREO_I32, heap,
					  dest_reg, doffset, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return SIZE_MAX;

	if (ref) {
		subtilis_ir_section_add_instr_no_reg(
		    p->current, SUBTILIS_OP_INSTR_REF, heap, err);
		if (err->type != SUBTILIS_ERROR_OK)
			return SIZE_MAX;
	}

	if (check_size) {
		subtilis_ir_section_add_label(p->current, skip_ref_label.label,
					      err);
		if (err->type != SUBTILIS_ERROR_OK)
			return SIZE_MAX;
	}

	soffset.integer += sizeof(int32_t);
	doffset.integer += sizeof(int32_t);

	for (i = 0; i < ints_to_copy; i++) {
		data.reg = subtilis_ir_section_add_instr(
		    p->current, SUBTILIS_OP_INSTR_LOADO_I32, source_reg,
		    soffset, err);
		if (err->type != SUBTILIS_ERROR_OK)
			return SIZE_MAX;
		subtilis_ir_section_add_instr_reg(p->current,
						  SUBTILIS_OP_INSTR_STOREO_I32,
						  data, dest_reg, doffset, err);
		if (err->type != SUBTILIS_ERROR_OK)
			return SIZE_MAX;

		soffset.integer += sizeof(int32_t);
		doffset.integer += sizeof(int32_t);
	}

	return ref_start.reg;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %r9, %rbp
movq %r8, %r13
movq %rcx, %r14
movq %rdx, %rbx
movq %rdi, %r12
movl 0x8(%rsi), %eax
movl %eax, 0x24(%rsp)
movq %rsi, %rdi
callq 0x357ea
movb %al, 0x7(%rsp)
testb %al, %al
movq %r13, 0x18(%rsp)
je 0x409ed
movq 0x48(%r12), %rdi
callq 0x2b774
movq %rax, 0x28(%rsp)
movq 0x48(%r12), %rdi
callq 0x2b774
movq %rax, %r15
jmp 0x409f1
pushq $-0x1
popq %r15
movq 0x78(%rsp), %r8
movq %rbx, %rax
testl %r14d, %r14d
jle 0x40a2e
movq %r15, %r13
movq 0x48(%r12), %rdi
movl %r14d, %ecx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
pushq $0x9
popq %rsi
movq %rbx, %rdx
movq %r8, %r15
callq 0x2a819
cmpl $0x0, (%r15)
je 0x40a28
pushq $-0x1
popq %rbx
jmp 0x40a8c
movq %r15, %r8
movq %r13, %r15
movq %rbx, 0x10(%rsp)
movq %rax, 0x30(%rsp)
movq 0x48(%r12), %rdi
movl %ebp, %ecx
pushq $0x12
popq %rsi
movq 0x18(%rsp), %rdx
callq 0x2a819
movq %rbp, %rcx
movq %rax, %rbp
pushq $-0x1
popq %rbx
movq 0x78(%rsp), %rax
cmpl $0x0, (%rax)
jne 0x40a8c
movq %rcx, 0x8(%rsp)
movq 0x48(%r12), %rdi
movl %r14d, %r8d
pushq $0x17
popq %rsi
movq %rbp, %rdx
movq 0x10(%rsp), %rcx
movq 0x78(%rsp), %r9
callq 0x2a8c1
movq 0x78(%rsp), %r8
cmpl $0x0, (%r8)
je 0x40a9e
movq %rbx, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movb 0x7(%rsp), %r13b
testb %r13b, %r13b
je 0x40aea
movq 0x48(%r12), %rdi
pushq $0x43
popq %rsi
movq %rbp, %rdx
movq 0x28(%rsp), %rbp
movq %rbp, %rcx
movq %r15, %r8
movq 0x78(%rsp), %r9
callq 0x2a8c1
movq 0x78(%rsp), %rdx
cmpl $0x0, (%rdx)
jne 0x40a8c
movq 0x48(%r12), %rdi
movq %rbp, %rsi
callq 0x2b781
movq 0x78(%rsp), %r8
cmpl $0x0, (%r8)
jne 0x40a8c
movq 0x8(%rsp), %rbp
leaq 0x4(%rbp), %rax
movq 0x48(%r12), %rdi
movl %eax, %ecx
pushq $0x12
popq %rsi
movq 0x18(%rsp), %rdx
callq 0x2a819
movq 0x78(%rsp), %rcx
cmpl $0x0, (%rcx)
jne 0x40a8c
leaq 0x4(%r14), %rcx
movq 0x48(%r12), %rdi
movl %ecx, %r8d
pushq $0x17
popq %rsi
movq %rax, %rdx
movq 0x10(%rsp), %rcx
movq 0x78(%rsp), %r9
callq 0x2a8c1
movq 0x78(%rsp), %r8
cmpl $0x0, (%r8)
jne 0x40a8c
leal 0x8(%rbp), %ecx
movq 0x48(%r12), %rdi
pushq $0x12
popq %rsi
movq 0x18(%rsp), %rdx
callq 0x2a819
movq %rax, %rbp
movq 0x78(%rsp), %rax
cmpl $0x0, (%rax)
jne 0x40a8c
movl %r14d, %r8d
addl $0x8, %r8d
movq 0x48(%r12), %rdi
pushq $0x17
popq %rsi
movq %rbp, %rdx
movq 0x10(%rsp), %rcx
movq 0x78(%rsp), %r9
callq 0x2a8c1
movq 0x78(%rsp), %r8
cmpl $0x0, (%r8)
jne 0x40a8c
cmpb $0x0, 0x70(%rsp)
je 0x40bc4
movq 0x48(%r12), %rdi
pushq $0x78
popq %rsi
movq %rbp, %rdx
movq %r8, %rcx
callq 0x2a997
movq 0x78(%rsp), %r8
cmpl $0x0, (%r8)
jne 0x40a8c
testb %r13b, %r13b
je 0x40be8
movq 0x48(%r12), %rdi
movq %r15, %rsi
movq %r8, %rdx
callq 0x2b781
movq 0x78(%rsp), %r8
cmpl $0x0, (%r8)
jne 0x40a8c
movq %rbx, %r13
movl 0x24(%rsp), %eax
incl %eax
movslq %eax, %rbp
movq 0x8(%rsp), %rax
addl $0xc, %eax
movq %rax, 0x8(%rsp)
addl $0xc, %r14d
pushq $0x12
popq %rbx
pushq $0x17
popq %r15
subq $0x1, %rbp
jb 0x40c74
movq 0x48(%r12), %rdi
movl 0x8(%rsp), %ecx
movl %ebx, %esi
movq 0x18(%rsp), %rdx
callq 0x2a819
movq 0x78(%rsp), %rcx
cmpl $0x0, (%rcx)
jne 0x40c6c
movq 0x48(%r12), %rdi
movl %r14d, %r8d
movl %r15d, %esi
movq %rax, %rdx
movq 0x10(%rsp), %rcx
movq 0x78(%rsp), %r9
callq 0x2a8c1
movq 0x78(%rsp), %r8
cmpl $0x0, (%r8)
jne 0x40c6c
movq 0x8(%rsp), %rax
addl $0x4, %eax
movq %rax, 0x8(%rsp)
addl $0x4, %r14d
jmp 0x40c0c
movq %r13, %rbx
jmp 0x40a8c
movq 0x30(%rsp), %rbx
jmp 0x40a8c