// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0xa0, %rsp
movq 0x18(%rbp), %rax
movb 0x10(%rbp), %al
movq %rdx, -0x10(%rbp)
movq %r8, -0x18(%rbp)
movq %rdi, -0x20(%rbp)
movq %rsi, -0x28(%rbp)
movq %rcx, -0x30(%rbp)
movq %r9, -0x38(%rbp)
andb $0x1, %al
movb %al, -0x39(%rbp)
movb $0x0, -0x89(%rbp)
movq $-0x1, -0x80(%rbp)
movq -0x28(%rbp), %rax
movl 0x8(%rax), %eax
addl $0x1, %eax
cltq
movq %rax, -0x98(%rbp)
movq -0x28(%rbp), %rdi
callq 0x4a040
testb $0x1, %al
jne 0x5e420
jmp 0x5e449
movb $0x1, -0x89(%rbp)
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
callq 0x39940
movq %rax, -0x78(%rbp)
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
callq 0x39940
movq %rax, -0x80(%rbp)
movq -0x38(%rbp), %rax
addq $0x0, %rax
movl %eax, -0x48(%rbp)
movq -0x30(%rbp), %rax
addq $0x0, %rax
movl %eax, -0x50(%rbp)
cmpl $0x0, -0x50(%rbp)
jle 0x5e49f
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
movq 0x18(%rbp), %r8
movq -0x10(%rbp), %rdx
movq -0x50(%rbp), %rcx
movl $0x9, %esi
callq 0x38230
movq %rax, -0x58(%rbp)
movq 0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5e49d
movq $-0x1, -0x8(%rbp)
jmp 0x5e7d3
jmp 0x5e4a7
movq -0x10(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
movq 0x18(%rbp), %r8
movq -0x18(%rbp), %rdx
movq -0x48(%rbp), %rcx
movl $0x12, %esi
callq 0x38230
movq %rax, -0x60(%rbp)
movq 0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5e4df
movq $-0x1, -0x8(%rbp)
jmp 0x5e7d3
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
movq 0x18(%rbp), %r9
movq -0x60(%rbp), %rdx
movq -0x10(%rbp), %rcx
movq -0x50(%rbp), %r8
movl $0x17, %esi
callq 0x38360
movq 0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5e517
movq $-0x1, -0x8(%rbp)
jmp 0x5e7d3
movslq -0x48(%rbp), %rax
addq $0x4, %rax
movl %eax, -0x48(%rbp)
movslq -0x50(%rbp), %rax
addq $0x4, %rax
movl %eax, -0x50(%rbp)
testb $0x1, -0x89(%rbp)
je 0x5e59b
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
movq 0x18(%rbp), %r9
movq -0x60(%rbp), %rdx
movq -0x78(%rbp), %rcx
movq -0x80(%rbp), %r8
movl $0x43, %esi
callq 0x38360
movq 0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5e56e
movq $-0x1, -0x8(%rbp)
jmp 0x5e7d3
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
movq -0x78(%rbp), %rsi
movq 0x18(%rbp), %rdx
callq 0x39960
movq 0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5e599
movq $-0x1, -0x8(%rbp)
jmp 0x5e7d3
jmp 0x5e59b
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
movq 0x18(%rbp), %r8
movq -0x18(%rbp), %rdx
movq -0x48(%rbp), %rcx
movl $0x12, %esi
callq 0x38230
movq %rax, -0x68(%rbp)
movq 0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5e5d3
movq $-0x1, -0x8(%rbp)
jmp 0x5e7d3
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
movq 0x18(%rbp), %r9
movq -0x68(%rbp), %rdx
movq -0x10(%rbp), %rcx
movq -0x50(%rbp), %r8
movl $0x17, %esi
callq 0x38360
movq 0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5e60b
movq $-0x1, -0x8(%rbp)
jmp 0x5e7d3
movslq -0x48(%rbp), %rax
addq $0x4, %rax
movl %eax, -0x48(%rbp)
movslq -0x50(%rbp), %rax
addq $0x4, %rax
movl %eax, -0x50(%rbp)
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
movq 0x18(%rbp), %r8
movq -0x18(%rbp), %rdx
movq -0x48(%rbp), %rcx
movl $0x12, %esi
callq 0x38230
movq %rax, -0x70(%rbp)
movq 0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5e659
movq $-0x1, -0x8(%rbp)
jmp 0x5e7d3
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
movq 0x18(%rbp), %r9
movq -0x70(%rbp), %rdx
movq -0x10(%rbp), %rcx
movq -0x50(%rbp), %r8
movl $0x17, %esi
callq 0x38360
movq 0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5e691
movq $-0x1, -0x8(%rbp)
jmp 0x5e7d3
testb $0x1, -0x39(%rbp)
je 0x5e6c9
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
movq 0x18(%rbp), %rcx
movq -0x70(%rbp), %rdx
movl $0x78, %esi
callq 0x38540
movq 0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5e6c7
movq $-0x1, -0x8(%rbp)
jmp 0x5e7d3
jmp 0x5e6c9
testb $0x1, -0x89(%rbp)
je 0x5e6ff
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
movq -0x80(%rbp), %rsi
movq 0x18(%rbp), %rdx
callq 0x39960
movq 0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5e6fd
movq $-0x1, -0x8(%rbp)
jmp 0x5e7d3
jmp 0x5e6ff
movslq -0x48(%rbp), %rax
addq $0x4, %rax
movl %eax, -0x48(%rbp)
movslq -0x50(%rbp), %rax
addq $0x4, %rax
movl %eax, -0x50(%rbp)
movq $0x0, -0x88(%rbp)
movq -0x88(%rbp), %rax
cmpq -0x98(%rbp), %rax
jae 0x5e7cb
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
movq 0x18(%rbp), %r8
movq -0x18(%rbp), %rdx
movq -0x48(%rbp), %rcx
movl $0x12, %esi
callq 0x38230
movq %rax, -0x68(%rbp)
movq 0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5e769
movq $-0x1, -0x8(%rbp)
jmp 0x5e7d3
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rdi
movq 0x18(%rbp), %r9
movq -0x68(%rbp), %rdx
movq -0x10(%rbp), %rcx
movq -0x50(%rbp), %r8
movl $0x17, %esi
callq 0x38360
movq 0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x5e79e
movq $-0x1, -0x8(%rbp)
jmp 0x5e7d3
movslq -0x48(%rbp), %rax
addq $0x4, %rax
movl %eax, -0x48(%rbp)
movslq -0x50(%rbp), %rax
addq $0x4, %rax
movl %eax, -0x50(%rbp)
movq -0x88(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
jmp 0x5e720
movq -0x58(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xa0, %rsp
popq %rbp
retq