// File: rossy[P]crossc/SPIRV-Cross/spirv_msl.cpp
// Function: spirv_cross::CompilerMSL::maybe_emit_array_assignment(unsigned int, unsigned int)
bool CompilerMSL::maybe_emit_array_assignment(uint32_t id_lhs, uint32_t id_rhs)
{
	// We only care about assignments of an entire array
	auto &type = expression_type(id_rhs);
	if (type.array.size() == 0)
		return false;

	auto *var = maybe_get<SPIRVariable>(id_lhs);

	// Is this a remapped, static constant? Don't do anything.
	if (var && var->remapped_variable && var->statically_assigned)
		return true;

	if (ir.ids[id_rhs].get_type() == TypeConstant && var && var->deferred_declaration)
	{
		// Special case, if we end up declaring a variable when assigning the constant array,
		// we can avoid the copy by directly assigning the constant expression.
		// This is likely necessary to be able to use a variable as a true look-up table, as it is unlikely
		// the compiler will be able to optimize the spvArrayCopy() into a constant LUT.
		// After a variable has been declared, we can no longer assign constant arrays in MSL unfortunately.
		statement(to_expression(id_lhs), " = ", constant_expression(get<SPIRConstant>(id_rhs)), ";");
		return true;
	}

	// Ensure the LHS variable has been declared
	auto *p_v_lhs = maybe_get_backing_variable(id_lhs);
	if (p_v_lhs)
		flush_variable_declaration(p_v_lhs->self);

	emit_array_copy(to_expression(id_lhs), id_rhs);
	register_write(id_lhs);

	return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0xa8(%rbp)
movl -0x18(%rbp), %esi
callq 0x1f760
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
addq $0x20, %rdi
callq 0x8650
cmpq $0x0, %rax
jne 0xfee68
movb $0x0, -0x1(%rbp)
jmp 0xff03a
movq -0xa8(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x116b0
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0xfee9f
movq -0x28(%rbp), %rax
testb $0x1, 0x5b(%rax)
je 0xfee9f
movq -0x28(%rbp), %rax
testb $0x1, 0x39(%rax)
je 0xfee9f
movb $0x1, -0x1(%rbp)
jmp 0xff03a
movq -0xa8(%rbp), %rdi
addq $0x8, %rdi
addq $0x18, %rdi
movl -0x18(%rbp), %eax
movl %eax, %esi
callq 0xbdb0
movq %rax, %rdi
callq 0xfa00
cmpl $0x3, %eax
jne 0xfef96
cmpq $0x0, -0x28(%rbp)
je 0xfef96
movq -0x28(%rbp), %rax
testb $0x1, 0x59(%rax)
je 0xfef96
movq -0xa8(%rbp), %rsi
movl -0x14(%rbp), %edx
leaq -0x48(%rbp), %rdi
callq 0x71b50
movq -0xa8(%rbp), %rdi
movl -0x18(%rbp), %esi
callq 0x31910
movq %rax, -0xb0(%rbp)
jmp 0xfef0d
movq -0xb0(%rbp), %rdx
movq -0xa8(%rbp), %rsi
leaq -0x68(%rbp), %rdi
callq 0x64bc0
jmp 0xfef26
movq -0xa8(%rbp), %rdi
leaq 0x4a0db(%rip), %rdx     # 0x14900f
leaq 0x4a16b(%rip), %r8      # 0x1490a6
leaq -0x48(%rbp), %rsi
leaq -0x68(%rbp), %rcx
callq 0xa51b0
jmp 0xfef4a
leaq -0x68(%rbp), %rdi
callq 0x7708
leaq -0x48(%rbp), %rdi
callq 0x7708
movb $0x1, -0x1(%rbp)
jmp 0xff03a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xfef88
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x7708
leaq -0x48(%rbp), %rdi
callq 0x7708
jmp 0xff048
movq -0xa8(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x1fa90
movq %rax, -0x80(%rbp)
cmpq $0x0, -0x80(%rbp)
je 0xfefc3
movq -0xa8(%rbp), %rdi
movq -0x80(%rbp), %rax
movl 0x8(%rax), %esi
callq 0x88710
movq -0xa8(%rbp), %rsi
movl -0x14(%rbp), %edx
leaq -0xa0(%rbp), %rdi
movq %rdi, -0xb8(%rbp)
callq 0x71b50
movq -0xa8(%rbp), %rdi
movq -0xb8(%rbp), %rsi
movl -0x18(%rbp), %edx
movq (%rdi), %rax
movq 0x150(%rax), %rax
callq *%rax
jmp 0xfefff
leaq -0xa0(%rbp), %rdi
callq 0x7708
movq -0xa8(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x1fd60
movb $0x1, -0x1(%rbp)
jmp 0xff03a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x7708
jmp 0xff048
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xc0, %rsp
popq %rbp
retq
movq -0x70(%rbp), %rdi
callq 0x7640
nopw %cs:(%rax,%rax)