// File: rossy[P]crossc/SPIRV-Cross/spirv_msl.cpp
// Function: spirv_cross::CompilerMSL::is_member_packable(spirv_cross::SPIRType&, unsigned int)
bool CompilerMSL::is_member_packable(SPIRType &ib_type, uint32_t index)
{
	// We've already marked it as packable
	if (has_member_decoration(ib_type.self, index, DecorationCPacked))
		return true;

	auto &mbr_type = get<SPIRType>(ib_type.member_types[index]);

	// Only 3-element vectors or 3-row matrices need to be packed.
	if (mbr_type.vecsize != 3)
		return false;

	// Only row-major matrices need to be packed.
	if (is_matrix(mbr_type) && !has_member_decoration(ib_type.self, index, DecorationRowMajor))
		return false;

	uint32_t component_size = mbr_type.width / 8;
	uint32_t unpacked_mbr_size = component_size * (mbr_type.vecsize + 1) * mbr_type.columns;
	if (is_array(mbr_type))
	{
		// If member is an array, and the array stride is larger than the type needs, don't pack it.
		// Take into consideration multi-dimentional arrays.
		uint32_t md_elem_cnt = 1;
		size_t last_elem_idx = mbr_type.array.size() - 1;
		for (uint32_t i = 0; i < last_elem_idx; i++)
			md_elem_cnt *= max(to_array_size_literal(mbr_type, i), 1U);

		uint32_t unpacked_array_stride = unpacked_mbr_size * md_elem_cnt;
		uint32_t array_stride = type_struct_member_array_stride(ib_type, index);
		return unpacked_array_stride > array_stride;
	}
	else
	{
		// Pack if there is not enough space between this member and next.
		// If last member, only pack if it's a row-major matrix.
		if (index < ib_type.member_types.size() - 1)
		{
			uint32_t mbr_offset_curr = get_member_decoration(ib_type.self, index, DecorationOffset);
			uint32_t mbr_offset_next = get_member_decoration(ib_type.self, index + 1, DecorationOffset);
			return unpacked_mbr_size > mbr_offset_next - mbr_offset_curr;
		}
		else
			return is_matrix(mbr_type);
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x68(%rbp)
movq -0x18(%rbp), %rax
movl 0x8(%rax), %esi
movl -0x1c(%rbp), %edx
movl $0xa, %ecx
callq 0x21f90
testb $0x1, %al
jne 0xfaae5
jmp 0xfaaee
movb $0x1, -0x1(%rbp)
jmp 0xfacb3
movq -0x18(%rbp), %rdi
addq $0x68, %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8630
movq -0x68(%rbp), %rdi
movl (%rax), %esi
callq 0xea90
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpl $0x3, 0x14(%rax)
je 0xfab22
movb $0x0, -0x1(%rbp)
jmp 0xfacb3
movq -0x68(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x20870
testb $0x1, %al
jne 0xfab35
jmp 0xfab5a
movq -0x68(%rbp), %rdi
movq -0x18(%rbp), %rax
movl 0x8(%rax), %esi
movl -0x1c(%rbp), %edx
movl $0x4, %ecx
callq 0x21f90
testb $0x1, %al
jne 0xfab5a
movb $0x0, -0x1(%rbp)
jmp 0xfacb3
movq -0x68(%rbp), %rdi
movq -0x28(%rbp), %rax
movl 0x10(%rax), %eax
shrl $0x3, %eax
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movq -0x28(%rbp), %rcx
movl 0x14(%rcx), %ecx
addl $0x1, %ecx
imull %ecx, %eax
movq -0x28(%rbp), %rcx
imull 0x18(%rcx), %eax
movl %eax, -0x30(%rbp)
movq -0x28(%rbp), %rsi
callq 0x208a0
testb $0x1, %al
jne 0xfab98
jmp 0xfac2f
movl $0x1, -0x34(%rbp)
movq -0x28(%rbp), %rdi
addq $0x20, %rdi
callq 0x8650
subq $0x1, %rax
movq %rax, -0x40(%rbp)
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
cmpq -0x40(%rbp), %rax
jae 0xfabff
movq -0x68(%rbp), %rdi
movq -0x28(%rbp), %rsi
movl -0x44(%rbp), %edx
callq 0x5df60
movl %eax, -0x48(%rbp)
movl $0x1, -0x4c(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0x4c(%rbp), %rsi
callq 0x9f7e0
movl (%rax), %eax
imull -0x34(%rbp), %eax
movl %eax, -0x34(%rbp)
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0xfabbb
movq -0x68(%rbp), %rdi
movl -0x30(%rbp), %eax
imull -0x34(%rbp), %eax
movl %eax, -0x50(%rbp)
movq -0x18(%rbp), %rsi
movl -0x1c(%rbp), %edx
callq 0x24170
movl %eax, -0x54(%rbp)
movl -0x50(%rbp), %eax
cmpl -0x54(%rbp), %eax
seta %al
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0xfacb3
movl -0x1c(%rbp), %eax
movq %rax, -0x70(%rbp)
movq -0x18(%rbp), %rdi
addq $0x68, %rdi
callq 0x8650
movq %rax, %rcx
movq -0x70(%rbp), %rax
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0xfaca1
movq -0x68(%rbp), %rdi
movq -0x18(%rbp), %rax
movl 0x8(%rax), %esi
movl -0x1c(%rbp), %edx
movl $0x23, %ecx
callq 0x231b0
movq -0x68(%rbp), %rdi
movl %eax, -0x58(%rbp)
movq -0x18(%rbp), %rax
movl 0x8(%rax), %esi
movl -0x1c(%rbp), %edx
addl $0x1, %edx
movl $0x23, %ecx
callq 0x231b0
movl %eax, -0x5c(%rbp)
movl -0x30(%rbp), %eax
movl -0x5c(%rbp), %ecx
subl -0x58(%rbp), %ecx
cmpl %ecx, %eax
seta %al
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0xfacb3
movq -0x68(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x20870
andb $0x1, %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x70, %rsp
popq %rbp
retq
nop