// File: /workspace/github_cpp_makefile_star2_O1/rossy[P]crossc/SPIRV-Cross/spirv_glsl.cpp
// Function: spirv_cross::CompilerGLSL::build_composite_combiner[abi:cxx11](unsigned int, unsigned int const*, unsigned int)
string CompilerGLSL::build_composite_combiner(uint32_t return_type, const uint32_t *elems, uint32_t length)
{
	uint32_t base = 0;
	string op;
	string subop;

	// Can only merge swizzles for vectors.
	auto &type = get<SPIRType>(return_type);
	bool can_apply_swizzle_opt = type.basetype != SPIRType::Struct && type.array.empty() && type.columns == 1;
	bool swizzle_optimization = false;

	for (uint32_t i = 0; i < length; i++)
	{
		auto *e = maybe_get<SPIRExpression>(elems[i]);

		// If we're merging another scalar which belongs to the same base
		// object, just merge the swizzles to avoid triggering more than 1 expression read as much as possible!
		if (can_apply_swizzle_opt && e && e->base_expression && e->base_expression == base)
		{
			// Only supposed to be used for vector swizzle -> scalar.
			assert(!e->expression.empty() && e->expression.front() == '.');
			subop += e->expression.substr(1, string::npos);
			swizzle_optimization = true;
		}
		else
		{
			// We'll likely end up with duplicated swizzles, e.g.
			// foobar.xyz.xyz from patterns like
			// OpVectorShuffle
			// OpCompositeExtract x 3
			// OpCompositeConstruct 3x + other scalar.
			// Just modify op in-place.
			if (swizzle_optimization)
			{
				if (backend.swizzle_is_function)
					subop += "()";

				// Don't attempt to remove unity swizzling if we managed to remove duplicate swizzles.
				// The base "foo" might be vec4, while foo.xyz is vec3 (OpVectorShuffle) and looks like a vec3 due to the .xyz tacked on.
				// We only want to remove the swizzles if we're certain that the resulting base will be the same vecsize.
				// Essentially, we can only remove one set of swizzles, since that's what we have control over ...
				// Case 1:
				//  foo.yxz.xyz: Duplicate swizzle kicks in, giving foo.yxz, we are done.
				//               foo.yxz was the result of OpVectorShuffle and we don't know the type of foo.
				// Case 2:
				//  foo.xyz: Duplicate swizzle won't kick in.
				//           If foo is vec3, we can remove xyz, giving just foo.
				if (!remove_duplicate_swizzle(subop))
					remove_unity_swizzle(base, subop);

				// Strips away redundant parens if we created them during component extraction.
				strip_enclosed_expression(subop);
				swizzle_optimization = false;
				op += subop;
			}
			else
				op += subop;

			if (i)
				op += ", ";
			subop = to_expression(elems[i]);
		}

		base = e ? e->base_expression : 0;
	}

	if (swizzle_optimization)
	{
		if (backend.swizzle_is_function)
			subop += "()";

		if (!remove_duplicate_swizzle(subop))
			remove_unity_swizzle(base, subop);
		// Strips away redundant parens if we created them during component extraction.
		strip_enclosed_expression(subop);
	}

	op += subop;
	return op;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movl %r8d, %ebp
movq %rcx, %r15
movq %rsi, %r14
leaq 0x10(%rdi), %r12
movq %r12, (%rdi)
xorl %eax, %eax
movq %rax, 0x8(%rdi)
movq %rdi, 0x10(%rsp)
movb %al, 0x10(%rdi)
leaq 0x28(%rsp), %rcx
movq %rcx, -0x10(%rcx)
movq %rax, -0x8(%rcx)
movb %al, (%rcx)
movq %rsi, %rdi
movl %edx, %esi
movq %r12, 0x58(%rsp)
callq 0xa426
xorl %ebx, %ebx
cmpl $0xc, 0xc(%rax)
movl $0x0, 0xc(%rsp)
je 0x44657
movq 0x20(%rax), %rcx
cmpq 0x28(%rax), %rcx
je 0x4464c
movl $0x0, 0xc(%rsp)
jmp 0x44657
cmpl $0x1, 0x18(%rax)
sete %al
movl %eax, 0xc(%rsp)
testl %ebp, %ebp
je 0x447f6
movl %ebp, %eax
movq %rax, 0x60(%rsp)
xorl %r12d, %r12d
movl 0xc(%rsp), %eax
xorb $0x1, %al
movl %eax, 0xc(%rsp)
xorl %ebx, %ebx
xorl %r13d, %r13d
movl (%r15,%r12,4), %esi
movq %r14, %rdi
callq 0x1ba12
movq %rax, %rbp
testq %rax, %rax
sete %al
orb 0xc(%rsp), %al
jne 0x4470f
movl 0xc(%rbp), %eax
testl %eax, %eax
setne %cl
cmpl %ebx, %eax
sete %al
andb %cl, %al
cmpb $0x1, %al
jne 0x4470f
cmpq $0x0, 0x18(%rbp)
je 0x44888
leaq 0x10(%rbp), %rsi
movq (%rsi), %rax
cmpb $0x2e, (%rax)
jne 0x44888
movl $0x1, %edx
leaq 0x38(%rsp), %rdi
movq $-0x1, %rcx
callq 0x6290
movq 0x38(%rsp), %rsi
movq 0x40(%rsp), %rdx
leaq 0x18(%rsp), %rdi
callq 0x60b0
movq 0x38(%rsp), %rdi
leaq 0x48(%rsp), %rax
cmpq %rax, %rdi
je 0x44707
movq 0x48(%rsp), %rsi
incq %rsi
callq 0x6260
movb $0x1, %r13b
jmp 0x447da
testb $0x1, %r13b
je 0x44773
cmpb $0x1, 0x620(%r14)
jne 0x44730
leaq 0x18(%rsp), %rdi
leaq 0x75235(%rip), %rsi     # 0xb9960
callq 0x64e0
movq %r14, %rdi
leaq 0x18(%rsp), %rsi
callq 0x33430
testb %al, %al
jne 0x44750
movq %r14, %rdi
movl %ebx, %esi
leaq 0x18(%rsp), %rdx
callq 0x443ee
leaq 0x18(%rsp), %rsi
callq 0x34c94
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rdx
movq 0x10(%rsp), %rdi
callq 0x60b0
xorl %r13d, %r13d
jmp 0x44787
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rdx
movq 0x10(%rsp), %rdi
callq 0x60b0
testq %r12, %r12
je 0x4479d
movq 0x10(%rsp), %rdi
leaq 0x76923(%rip), %rsi     # 0xbb0bb
callq 0x64e0
movl (%r15,%r12,4), %edx
leaq 0x38(%rsp), %rbx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x345e6
leaq 0x18(%rsp), %rdi
movq %rbx, %rsi
callq 0x6310
movq 0x38(%rsp), %rdi
leaq 0x48(%rsp), %rax
cmpq %rax, %rdi
je 0x447da
movq 0x48(%rsp), %rsi
incq %rsi
callq 0x6260
testq %rbp, %rbp
je 0x447e4
movl 0xc(%rbp), %ebx
jmp 0x447e6
xorl %ebx, %ebx
incq %r12
cmpq %r12, 0x60(%rsp)
jne 0x44678
jmp 0x447f9
xorl %r13d, %r13d
testb $0x1, %r13b
je 0x44844
cmpb $0x1, 0x620(%r14)
jne 0x4481a
leaq 0x75150(%rip), %rsi     # 0xb9960
leaq 0x18(%rsp), %rdi
callq 0x64e0
leaq 0x18(%rsp), %rsi
movq %r14, %rdi
callq 0x33430
testb %al, %al
jne 0x4483a
leaq 0x18(%rsp), %rdx
movq %r14, %rdi
movl %ebx, %esi
callq 0x443ee
leaq 0x18(%rsp), %rsi
callq 0x34c94
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rdx
movq 0x10(%rsp), %rdi
callq 0x60b0
movq 0x18(%rsp), %rdi
leaq 0x28(%rsp), %rax
cmpq %rax, %rdi
je 0x44874
movq 0x28(%rsp), %rsi
incq %rsi
callq 0x6260
movq 0x10(%rsp), %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x76340(%rip), %rdi     # 0xbabcf
leaq 0x734c2(%rip), %rsi     # 0xb7d58
leaq 0x76369(%rip), %rcx     # 0xbac06
movl $0x17ba, %edx           # imm = 0x17BA
callq 0x61b0
jmp 0x448d0
jmp 0x448d0
movq %rax, %rbx
movq 0x38(%rsp), %rdi
leaq 0x48(%rsp), %rax
cmpq %rax, %rdi
je 0x448d3
movq 0x48(%rsp), %rsi
incq %rsi
callq 0x6260
jmp 0x448d3
jmp 0x448d0
jmp 0x448d0
movq %rax, %rbx
movq 0x18(%rsp), %rdi
leaq 0x28(%rsp), %rax
cmpq %rax, %rdi
je 0x448ef
movq 0x28(%rsp), %rsi
incq %rsi
callq 0x6260
movq 0x10(%rsp), %rax
movq (%rax), %rdi
movq 0x58(%rsp), %rax
cmpq %rax, %rdi
je 0x4490c
movq (%rax), %rsi
incq %rsi
callq 0x6260
movq %rbx, %rdi
callq 0x64a0