// File: /workspace/github_c_makefile_star2_O1/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, %rbx
movq %rdx, %r14
movq %rdi, %r12
movl 0x8(%rsi), %eax
movl %eax, 0x24(%rsp)
movq %rsi, %rdi
callq 0x37815
movl %eax, %r15d
testb %al, %al
je 0x430c0
movq 0x48(%r12), %rdi
callq 0x2d00a
movq %rax, 0x30(%rsp)
movq 0x48(%r12), %rdi
callq 0x2d00a
movq %rax, 0x18(%rsp)
jmp 0x430c9
movq $-0x1, 0x18(%rsp)
movq 0x78(%rsp), %r8
movq %r14, 0x8(%rsp)
testl %ebx, %ebx
jle 0x43109
movq 0x48(%r12), %rdi
movl %ebx, %ecx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
movl $0x9, %esi
movq 0x8(%rsp), %rdx
movq %r8, %r14
callq 0x2c00f
movq %r14, %r8
movq %rax, %r14
movq $-0x1, %rax
cmpl $0x0, (%r8)
jne 0x4316f
movq 0x48(%r12), %rdi
movl %ebp, %ecx
movl $0x12, %esi
movq %r13, %rdx
callq 0x2c00f
movq %rbp, %rcx
movq %rax, %rbp
movq $-0x1, %rax
movq 0x78(%rsp), %rdx
cmpl $0x0, (%rdx)
jne 0x4316f
movq %r13, 0x10(%rsp)
movq %rcx, 0x28(%rsp)
movq 0x48(%r12), %rdi
movl %ebx, %r8d
movl $0x17, %esi
movq %rbp, %rdx
movq 0x8(%rsp), %rcx
movq 0x78(%rsp), %r9
callq 0x2c0c2
movq 0x78(%rsp), %r8
cmpl $0x0, (%r8)
je 0x4317e
movq $-0x1, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %r15d, %r13d
testb %r15b, %r15b
je 0x431cc
movq 0x48(%r12), %rdi
movl $0x43, %esi
movq %rbp, %rdx
movq 0x30(%rsp), %r15
movq %r15, %rcx
movq 0x18(%rsp), %r8
movq 0x78(%rsp), %r9
callq 0x2c0c2
movq 0x78(%rsp), %rdx
cmpl $0x0, (%rdx)
jne 0x43168
movq 0x48(%r12), %rdi
movq %r15, %rsi
callq 0x2d017
movq 0x78(%rsp), %r8
cmpl $0x0, (%r8)
jne 0x43168
movq 0x28(%rsp), %rbp
leaq 0x4(%rbp), %rax
movq 0x48(%r12), %rdi
movl %eax, %ecx
movl $0x12, %esi
movq 0x10(%rsp), %rdx
callq 0x2c00f
movq 0x78(%rsp), %rcx
cmpl $0x0, (%rcx)
jne 0x43168
leaq 0x4(%rbx), %rcx
movq 0x48(%r12), %rdi
movl %ecx, %r8d
movl $0x17, %esi
movq %rax, %rdx
movq 0x8(%rsp), %rcx
movq 0x78(%rsp), %r9
callq 0x2c0c2
movq 0x78(%rsp), %r8
cmpl $0x0, (%r8)
jne 0x43168
leal 0x8(%rbp), %ecx
movq 0x48(%r12), %rdi
movl $0x12, %esi
movq 0x10(%rsp), %rdx
callq 0x2c00f
movq %rax, %rbp
movq 0x78(%rsp), %rax
cmpl $0x0, (%rax)
jne 0x43168
movl %ebx, %r8d
addl $0x8, %r8d
movq 0x48(%r12), %rdi
movl $0x17, %esi
movq %rbp, %rdx
movq 0x8(%rsp), %rcx
movq 0x78(%rsp), %r9
callq 0x2c0c2
movq 0x78(%rsp), %r8
cmpl $0x0, (%r8)
jne 0x43168
cmpb $0x0, 0x70(%rsp)
je 0x432b0
movq 0x48(%r12), %rdi
movl $0x78, %esi
movq %rbp, %rdx
movq %r8, %rcx
callq 0x2c19f
movq 0x78(%rsp), %r8
cmpl $0x0, (%r8)
jne 0x43168
testb %r13b, %r13b
je 0x432d6
movq 0x48(%r12), %rdi
movq 0x18(%rsp), %rsi
movq %r8, %rdx
callq 0x2d017
movq 0x78(%rsp), %r8
cmpl $0x0, (%r8)
jne 0x43168
movl 0x24(%rsp), %eax
incl %eax
je 0x43354
movq %r14, %r13
movslq %eax, %r14
addl $0xc, %ebx
movq 0x28(%rsp), %rbp
addl $0xc, %ebp
movq 0x48(%r12), %rdi
movl %ebp, %ecx
movl $0x12, %esi
movq 0x10(%rsp), %rdx
callq 0x2c00f
movq 0x78(%rsp), %rcx
cmpl $0x0, (%rcx)
jne 0x43168
movq 0x48(%r12), %rdi
movl %ebx, %r8d
movl $0x17, %esi
movq %rax, %rdx
movq 0x8(%rsp), %rcx
movq 0x78(%rsp), %r9
callq 0x2c0c2
movq 0x78(%rsp), %r8
cmpl $0x0, (%r8)
jne 0x43168
addl $0x4, %ebp
addl $0x4, %ebx
decq %r14
jne 0x432ef
movq %r13, %rax
jmp 0x4316f
movq %r14, %rax
jmp 0x4316f